static void lt_request_cli(void *arg) { int ret; lthread_t *lt = NULL; proxy_conn_t *priv_conn = proxy_conn_create(-1, 1); proxy_conn_t *proxy_conn = (proxy_conn_t*)arg; DEFINE_LTHREAD; lthread_detach(); fprintf(stderr, "request new client\n"); ret = tcp_dial_ipv4(&priv_conn->conn, "192.168.6.1:80"); if(0 != ret) { proxy_conn_free(priv_conn); proxy_conn_free(proxy_conn); return; } fprintf(stderr, "dial priv conn ok\n"); priv_conn->other = proxy_conn; proxy_conn->other = priv_conn; //lthread_create(<1, (void*)lt_proxy_loop, (void*)priv_conn); lthread_create(<, (void*)lt_proxy_loop, (void*)proxy_conn); lt_proxy_loop(priv_conn); lthread_join(lt, NULL, LTHREAD_FOREVER); void* data = NULL; kstring_t *buf = NULL; while(0 == chan_recv(priv_conn->write_ch, &data)) { if(data != NULL) { buf = (kstring_t*)data; ks_free(buf); free(buf); } else { //mark as end break; } } while(0 == chan_recv(proxy_conn->write_ch, &data)) { if(data != NULL) { buf = (kstring_t*)data; ks_free(buf); free(buf); } else { //mark as end break; } } proxy_conn_free(priv_conn); proxy_conn_free(proxy_conn); }
static void server_release(proxy_server *srv) { void* data = NULL; //only writer can close the channel chan_close(srv->accepts_ch); while(0 == chan_recv(srv->accepts_ch, &data)) { if(data != NULL) { proxy_conn_free(data); } } }
void whisper(void* args) { long *r = (long *)go_malloc(sizeof(long)); /*channels *chans = (channels *)args;*/ channels *chans; writebarrierptr((void**)&chans, args); *r = *(long *)chan_recv(chans->right); *r += 1; chan_send(chans->left, r); }
void go_main() { // a slowdown in this scenario for gccgo-6.3.0 but not for gcc-7.1.0 or Go runtime_gomaxprocsfunc(getproccount()); const long n = 500000; /*void *leftmost = chan_make(0);*/ void *leftmost; writebarrierptr(&leftmost, chan_make(0)); /*void *right = leftmost;*/ void *right; writebarrierptr(&right, leftmost); /*void *left = leftmost;*/ void *left; writebarrierptr(&left, leftmost); long i; long res; channels *chans; for(i = 0; i < n; i++) { /*right = chan_make(0);*/ writebarrierptr(&right, chan_make(0)); /*chans = (channels *)go_malloc(sizeof(channels));*/ writebarrierptr((void**)&chans, go_malloc(sizeof(channels))); /*chans->left = left;*/ writebarrierptr(&(chans->left), left); /*chans->right = right;*/ writebarrierptr(&(chans->right), right); __go_go(whisper, chans); /*left = right;*/ writebarrierptr(&left, right); } __go_go(first_whisper, right); res = *(long *)chan_recv(leftmost); printf("%ld\n", res); }
// A select statement chooses which of a set of possible send or receive // operations will proceed. The return value indicates which channel's // operation has proceeded. If more than one operation can proceed, one is // selected randomly. If none can proceed, -1 is returned. Select is intended // to be used in conjunction with a switch statement. In the case of a receive // operation, the received value will be pointed to by the provided pointer. In // the case of a send, the value at the same index as the channel will be sent. int chan_select(chan_t* recv_chans[], int recv_count, void** recv_out, chan_t* send_chans[], int send_count, void* send_msgs[]) { // TODO: Add support for blocking selects. select_op_t candidates[recv_count + send_count]; int count = 0; int i; // Determine receive candidates. for (i = 0; i < recv_count; i++) { chan_t* chan = recv_chans[i]; if (chan_can_recv(chan)) { select_op_t op; op.recv = 1; op.chan = chan; op.index = i; candidates[count++] = op; } } // Determine send candidates. for (i = 0; i < send_count; i++) { chan_t* chan = send_chans[i]; if (chan_can_send(chan)) { select_op_t op; op.recv = 0; op.chan = chan; op.msg_in = send_msgs[i]; op.index = i + recv_count; candidates[count++] = op; } } if (count == 0) { return -1; } // Seed rand using current time in nanoseconds. struct timespec ts; current_utc_time(&ts); srand(ts.tv_nsec); // Select candidate and perform operation. select_op_t select = candidates[rand() % count]; if (select.recv && chan_recv(select.chan, recv_out) != 0) { return -1; } else if (!select.recv && chan_send(select.chan, select.msg_in) != 0) { return -1; } return select.index; }