1 /* go-send-nb-small.c -- nonblocking send of something small on a channel.
3 Copyright 2009 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
13 /* Prepare to send something on a nonblocking channel. Return true if
14 we acquired the channel, false if we did not acquire it because
15 there is no space to send a value. */
18 __go_send_nonblocking_acquire (struct __go_channel
*channel
)
23 i
= pthread_mutex_lock (&channel
->lock
);
26 while (channel
->selected_for_send
)
28 i
= pthread_cond_wait (&channel
->cond
, &channel
->lock
);
32 if (channel
->is_closed
)
34 i
= pthread_mutex_unlock (&channel
->lock
);
36 __go_panic_msg ("send on closed channel");
39 if (channel
->num_entries
> 0)
40 has_space
= ((channel
->next_store
+ 1) % channel
->num_entries
41 != channel
->next_fetch
);
44 /* This is a synchronous channel. If somebody is current
45 sending, then we can't send. Otherwise, see if somebody is
46 waiting to receive, or see if we can synch with a select. */
47 if (channel
->waiting_to_send
)
49 /* Some other goroutine is currently sending on this
50 channel, which means that we can't. */
53 else if (channel
->waiting_to_receive
)
55 /* Some other goroutine is waiting to receive a value, so we
56 can send directly to them. */
59 else if (__go_synch_with_select (channel
, 1))
61 /* We found a select waiting to receive data, so we can send
63 __go_broadcast_to_select (channel
);
68 /* Otherwise, we can't send, because nobody is waiting to
75 channel
->waiting_to_send
= 1;
76 __go_assert (channel
->next_store
== 0);
82 i
= pthread_mutex_unlock (&channel
->lock
);
91 /* Send something 64 bits or smaller on a channel. */
94 __go_send_nonblocking_small (struct __go_channel
*channel
, uint64_t val
)
99 __go_assert (channel
->element_type
->__size
<= sizeof (uint64_t));
101 if (!__go_send_nonblocking_acquire (channel
))
104 channel
->data
[channel
->next_store
] = val
;
106 __go_send_release (channel
);