Esempio n. 1
0
void first_whisper(void* chan)
{
	long *v = (long *)go_malloc(sizeof(long));

	*v = 1;
	chan_send(chan, v);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
int main(void)
{
  switch_t s;
  chan_t c;
  packet_t p;
  path_t in;
  int sock;

  crypt_init();
  s = switch_new(0);

  if(util_loadjson(s) != 0 || (sock = util_server(0,1000)) <= 0)
  {
    printf("failed to startup %s or %s\n", strerror(errno), crypt_err());
    return -1;
  }

  printf("loaded hashname %s\n",s->id->hexname);

  // create/send a ping packet  
  c = chan_new(s, bucket_get(s->seeds, 0), "link", 0);
  p = chan_packet(c);
  chan_send(c, p);
  util_sendall(s,sock);

  in = path_new("ipv4");
  while(util_readone(s, sock, in) == 0)
  {
    switch_loop(s);

    while((c = switch_pop(s)))
    {
      printf("channel active %d %s %s\n",c->state,c->hexid,c->to->hexname);
      if(util_cmp(c->type,"connect") == 0) ext_connect(c);
      if(util_cmp(c->type,"link") == 0) ext_link(c);
      if(util_cmp(c->type,"path") == 0) ext_path(c);
      while((p = chan_pop(c)))
      {
        printf("unhandled channel packet %.*s\n", p->json_len, p->json);      
        packet_free(p);
      }
      if(c->state == ENDED) chan_free(c);
    }

    util_sendall(s,sock);
  }

  perror("exiting");
  return 0;
}
Esempio n. 4
0
// chunk the packet out
void thtp_send(chan_t c, lob_t req)
{
  lob_t chunk;
  unsigned char *raw;
  unsigned short len, space;
  if(!c || !req) return;
  DEBUG_PRINTF("THTP sending %.*s %.*s",req->json_len,req->json,req->body_len,req->body);
  raw = lob_raw(req);
  len = lob_len(req);
  while(len)
  {
    chunk = chan_packet(c);
    if(!chunk) return; // TODO backpressure
    space = lob_space(chunk);
    if(space > len) space = len;
    lob_body(chunk,raw,space);
    if(len==space) lob_set(chunk,"end","true",4);
    chan_send(c,chunk);
    raw+=space;
    len-=space;
  }
}
Esempio n. 5
0
File: chan.c Progetto: irr/chan
// 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;
}
Esempio n. 6
0
void lt_main(void *arg)
{
    int fd, opt = 1;
    proxy_server *srv = (proxy_server*)arg;
    lthread_t *lt_accept = NULL;
    struct sockaddr cin = {0};
    socklen_t addrlen = sizeof(struct sockaddr);
    proxy_conn_t *proxy = NULL;

    DEFINE_LTHREAD;
    lthread_detach();

    srv->listen_fd = create_listener("0.0.0.0", 9000);
    if(srv->listen_fd < 0) {
        exit(1);
    }
    fprintf(stderr, "listener creating :9000\n");

    lthread_create(&lt_accept, (void*)lt_accept_loop, (void*)srv);

    while(!srv->is_die) {
        fd = lthread_accept(srv->listen_fd, &cin, &addrlen);
        if(fd < 0) {
            perror("accept error");
            break;
        }
        if(srv->quiting) {
            lthread_close(fd);
            break;
        }
        if(srv->is_die) {
            //already die, close and break
            lthread_close(fd);
            fprintf(stderr, "server already die :9000\n");
            break;
        }

        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == -1) {
            perror("failed to set SOREUSEADDR on socket");
            break;
        }

        fprintf(stderr, "accept new client\n");
        proxy = proxy_conn_create(fd, 0);
        if(0 != chan_send(srv->accepts_ch, proxy)) {
            //send failed, free proxy
            proxy_conn_free(proxy);
            break;
        }

        //yield myself
        lthread_sleep((uint64_t)0);
    }
    if(-1 != srv->listen_fd) {
        close(srv->listen_fd);
        srv->listen_fd = -1;
    }
    if(!srv->is_die) {
        srv->is_die = 1;
        chan_close(srv->die_ch);
        fprintf(stderr, "srv die\n");
    }

    fprintf(stderr, "lt_accept end\n");
    lthread_join(lt_accept, NULL, LTHREAD_FOREVER);

    //server release
    server_release(srv);
}