Exemplo n.º 1
0
void *
fqd_worker_thread(void *arg)
{
  struct incoming_message *m;
  int tindex = *(int*) arg;

  ck_fifo_spsc_t *q = &work_queues[tindex];
  uint32_t *backlog = &work_queue_backlogs[tindex];

  while (!worker_thread_shutdown) {
    if (!CK_FIFO_SPSC_ISEMPTY(q)) {
      if (ck_fifo_spsc_dequeue(q, &m)) {
        if (m != NULL) {
          ck_pr_dec_32(backlog);
          fq_msg *copy = fq_msg_alloc_BLANK(m->msg->payload_len);
          if (copy == NULL) {
            continue;
          }
          memcpy(copy, m->msg, sizeof(fq_msg) + m->msg->payload_len);
          /* reset the refcnt on the copy since the memcpy above will have overwritten it */
          copy->refcnt = 1;
          /* the copy will be freed as normal so eliminate cleanup_stack pointer */
          copy->cleanup_stack = NULL;

          /* we are done with the incoming message, deref */
          fq_msg_deref(m->msg);

          fqd_inject_message(m->client, copy);
	  fqd_remote_client_deref((remote_client *)m->client);
          free(m);
        }
      }
    } else {
      usleep(1000);
    }
  }

  /* drain the queue before exiting */
  if (!CK_FIFO_SPSC_ISEMPTY(q)) {
    ck_fifo_spsc_dequeue_lock(q);
    if (ck_fifo_spsc_dequeue(q, &m)) {
      if (m != NULL) {
        ck_pr_dec_32(backlog);
        fq_msg *copy = fq_msg_alloc_BLANK(m->msg->payload_len);
        memcpy(copy, m->msg, sizeof(fq_msg) + m->msg->payload_len);
        /* the copy will be freed as normal so eliminate cleanup_stack pointer */
        copy->cleanup_stack = NULL;
        /* we are done with the incoming message, drop it on it's cleanup stack */
        fqd_inject_message(m->client, copy);
        fq_msg_deref(m->msg);
        free(m);
      }
    }
    ck_fifo_spsc_dequeue_unlock(q);
  }
  usleep(10);
  return NULL;
}
Exemplo n.º 2
0
buffered_msg_reader *fq_buffered_msg_reader_alloc(int fd, uint32_t peermode) {
  buffered_msg_reader *br;
  br = calloc(1, sizeof(*br));
  br->fd = fd;
  br->peermode = peermode;
  br->msg = fq_msg_alloc_BLANK(0);
  return br;
}
Exemplo n.º 3
0
int main(int argc, char **argv) {
  hrtime_t s0, s, f, f0;
  uint64_t cnt = 0, icnt = 0;
  int psize = 0, i = 0;
  fq_client c;
  fq_msg *m;
  char *fq_debug = getenv("FQ_DEBUG");
  if(fq_debug) fq_debug_set_bits(atoi(fq_debug));
  signal(SIGPIPE, SIG_IGN);
  fq_client_init(&c, 0, logger);
  if(argc < 5) {
    fprintf(stderr, "%s <host> <port> <user> <pass> [size [count]]\n",
            argv[0]);
    exit(-1);
  }
  fq_client_creds(c, argv[1], atoi(argv[2]), argv[3], argv[4]);
  fq_client_heartbeat(c, 1000);
  fq_client_set_backlog(c, 10000, 100);
  fq_client_connect(c);

  if(argc > 5) {
     psize = atoi(argv[5]);
  }
  printf("payload size -> %d\n", psize);
  if(argc > 6) {
    send_count = atoi(argv[6]);
  }
  printf("message count -> %d\n", send_count);

  s0 = s = fq_gethrtime();
  while(i < send_count || fq_client_data_backlog(c) > 0) {
    if(i < send_count) {
      m = fq_msg_alloc_BLANK(psize);
      memset(m->payload, 0, psize);
      fq_msg_exchange(m, "maryland", 8);
      fq_msg_route(m, "test.prefix.boo", 15);
      fq_msg_id(m, NULL);
      fq_client_publish(c, m);
      cnt++;
      i++;
      fq_msg_free(m);
    }
    else usleep(100);


    f = fq_gethrtime();
    if(f-s > 1000000000) {
      print_rate(c, s, f, cnt, icnt);
      icnt = 0;
      cnt = 0;
      s = f;
    }
  }
  f0 = fq_gethrtime();
  print_rate(c, s0, f0, i, 0);
  (void) argc;
  return 0;
}
Exemplo n.º 4
0
static int
fqd_http_message_headers_complete(http_parser *p) {
#define EXPECT_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
  const char *clen;
  static char *expect_continue = EXPECT_CONTINUE;
  static int expect_continue_len = sizeof(EXPECT_CONTINUE)-1;
  struct http_req *req = p->data;
  if(req->expect_continue == HTTP_EXPECT_CONTINUE) {
    while(write(req->client->fd, expect_continue, expect_continue_len) == -1 && errno == EINTR);
    req->expect_continue = HTTP_EXPECT_SENT;
  }
  clen = fqd_http_header(req, "content-length");
  if(!strcmp(req->url, "/submit") && clen) {
    req->body_len = atoi(clen);
    req->msg = fq_msg_alloc_BLANK(req->body_len);
  }
  return 0;
}
Exemplo n.º 5
0
Arquivo: fqc.c Projeto: denji/fq
int main(int argc, char **argv) {
  hrtime_t s0, s, f, f0;
  uint64_t cnt = 0, icnt = 0;
  int psize = 0, i = 0, rcvd = 0;
  fq_client c;
  fq_bind_req breq;
  fq_msg *m;
  signal(SIGPIPE, SIG_IGN);
  fq_client_init(&c, 0, logger);
  if(argc < 5) {
    fprintf(stderr, "%s <host> <port> <user> <pass> [size [count]]\n",
            argv[0]);
    exit(-1);
  }
  fq_client_creds(c, argv[1], atoi(argv[2]), argv[3], argv[4]);
  fq_client_heartbeat(c, 1000);
  fq_client_set_backlog(c, 10000, 100);
  fq_client_connect(c);

  memset(&breq, 0, sizeof(breq));
  memcpy(breq.exchange.name, "maryland", 8);
  breq.exchange.len = 8;
  breq.peermode = 0;
  breq.program = (char *)"prefix:\"test.prefix.\"";

  fq_client_bind(c, &breq);
  while(breq.out__route_id == 0) usleep(100);
  printf("route set -> %u\n", breq.out__route_id);
  if(breq.out__route_id == FQ_BIND_ILLEGAL) {
    fprintf(stderr, "Failure to bind...\n");
    exit(-1);
  }

  if(argc > 5) {
     psize = atoi(argv[5]);
  }
  printf("payload size -> %d\n", psize);
  if(argc > 6) {
    send_count = atoi(argv[6]);
  }
  printf("message count -> %d\n", send_count);

  s0 = s = fq_gethrtime();
  while(i < send_count || fq_client_data_backlog(c) > 0) {
    if(i < send_count) {
      m = fq_msg_alloc_BLANK(psize);
      memset(m->payload, 0, psize);
      fq_msg_exchange(m, "maryland", 8);
      fq_msg_route(m, "test.prefix.foo", 15);
      fq_msg_id(m, NULL);
      fq_client_publish(c, m);
      cnt++;
      i++;
      fq_msg_free(m);
    }
    else usleep(100);


    f = fq_gethrtime();
    while(m = fq_client_receive(c)) {
      icnt++;
      rcvd++;
      fq_msg_deref(m);
    }
    if(f-s > 1000000000) {
      print_rate(c, s, f, cnt, icnt);
      icnt = 0;
      cnt = 0;
      s = f;
    }
  }
  f0 = fq_gethrtime();
  print_rate(c, s0, f0, i, 0);
  do {
    icnt=0;
    while(m = fq_client_receive(c)) {
      icnt++;
      rcvd++;
      fq_msg_deref(m);
    }
  } while(rcvd < send_count);
  f0 = fq_gethrtime();
  print_rate(c, s0, f0, 0, rcvd);
  printf("Total received during test: %d\n", rcvd);

  (void) argc;
  return 0;
}
Exemplo n.º 6
0
Arquivo: fq_utils.c Projeto: denji/fq
/*
 * return 0: keep going (to write path)
 * return -1: busted
 */
int
fq_buffered_msg_read(buffered_msg_reader *f,
                     void (*f_msg_handler)(void *, fq_msg *),
                     void *closure) {
  int rv;
  if(f->into_body < f->msg.payload_len) {
    assert(f->copy);
    /* we need to be reading a largish payload */
    while((rv = read(f->fd, f->copy->payload + f->into_body,
                     f->copy->payload_len - f->into_body)) == -1 && errno == EINTR);
    if(rv < 0 && errno == EAGAIN) return 0;
    if(rv <= 0) {
      fq_debug(FQ_DEBUG_IO, "read error: %s\n", rv < 0 ? strerror(errno) : "end-of-line");
      return -1;
    }
    fq_debug(FQ_DEBUG_MSG, "%p <-- %d bytes for payload\n", (void *)f, rv);
    f->into_body += rv;
    if(f->into_body == f->copy->payload_len) {
      f->into_body = 0;
      goto message_done;
    }
  }
  while((rv = read(f->fd, f->scratch+f->nread, sizeof(f->scratch)-f->nread)) == -1 &&
        errno == EINTR);
  fq_debug(FQ_DEBUG_IO, "%p <-- %d bytes @ %d (%d)\n", (void *)f, rv, (int)f->nread,
          (int)f->nread + (rv > 0) ? rv : 0);
  if(rv == -1 && errno == EAGAIN) return 0;
  if(rv <= 0) return -1;
  f->nread += rv;

  while(f->nread>0) {
    uint32_t body_available;
    int body_start;
    body_start = parse_message_headers(f->peermode,
                                       f->scratch+f->off, f->nread-f->off,
                                       &f->msg);
    f->into_body = 0;
    fq_debug(FQ_DEBUG_MSG, "%d = parse(+%d, %d) -> %d\n",
            body_start, f->off, (int)f->nread-f->off,
            body_start ? (int)f->msg.payload_len : 0);
    if(body_start < 0) return -1;
    if(!body_start) {
      fq_debug(FQ_DEBUG_MSG, "incomplete message header...\n");
      memmove(f->scratch, f->scratch + f->off, f->nread - f->off);
      f->nread -= f->off;
      f->off = 0;
      return 0;
    }

    /* We have a message... or the formal beginnings of one */
    f->copy = fq_msg_alloc_BLANK(f->msg.payload_len);
    memcpy(f->copy, &f->msg, sizeof(f->msg));

    f->off += body_start;
    body_available = f->nread - f->off;
    if(f->copy->payload_len < body_available) body_available = f->copy->payload_len;
    memcpy(f->copy->payload, f->scratch+f->off, body_available);
    if(body_available == f->copy->payload_len) {
      f->off += body_available;
     message_done:
      f->copy->refcnt = 1;
      fq_debug(FQ_DEBUG_MSG, "message read... injecting\n");
      f_msg_handler(closure, f->copy);
      f->copy = NULL;
      memset(&f->msg, 0, sizeof(f->msg));
    }
    else {
      f->nread = 0;
      f->off = 0;
      f->into_body = body_available;
      fq_debug(FQ_DEBUG_MSG, "incomplete message... (%d needed)\n",
             (int)f->msg.payload_len - (int)f->into_body);
      return 0;
    }
  }
  return 0;
}
Exemplo n.º 7
0
/*
 * return 0: keep going (to write path)
 * return -1: busted
 * 
 * Read into one of N buffers so the processing thread 
 * can do the work separate from the read
 */
int
fq_buffered_msg_read(buffered_msg_reader *f,
                     void (*f_msg_handler)(void *, fq_msg *),
                     void *closure) {
  int rv;
  static char scratch_buf[IN_READ_BUFFER_SIZE];
  while(f->into_body < f->msg->payload_len) {
    fq_assert(f->copy);
    /* we need to be reading a largish payload */
    if(f->into_body >= MAX_MESSAGE_SIZE) {
      /* read into a scratch buffer */
      size_t readsize = f->copy->payload_len - f->into_body;
      if(readsize > sizeof(scratch_buf)) readsize = sizeof(scratch_buf);
      while((rv = read(f->fd, scratch_buf, readsize)) == -1 && errno == EINTR);
    }
    else {
      while((rv = read(f->fd, f->copy->payload + f->into_body,
                       CAPPED(f->copy->payload_len) - f->into_body)) == -1 && errno == EINTR);
    }
    if(rv < 0 && errno == EAGAIN) return 0;
    if(rv <= 0) {
      fq_debug(FQ_DEBUG_IO, "read error: %s\n", rv < 0 ? strerror(errno) : "end-of-line");
      return -1;
    }
    fq_debug(FQ_DEBUG_MSG, "%p <-- %d bytes for payload\n", (void *)f, rv);
    f->into_body += rv;
    if(f->into_body == f->copy->payload_len) {
      f->into_body = 0;
      goto message_done;
    }
  }
  while((rv = read(f->fd, f->scratch+f->nread, sizeof(f->scratch)-f->nread)) == -1 &&
        errno == EINTR);
  fq_debug(FQ_DEBUG_IO, "%p <-- %d bytes @ %d (%d)\n", (void *)f, rv, (int)f->nread,
          (int)f->nread + ((rv > 0) ? rv : 0));
  if(rv == -1 && errno == EAGAIN) return 0;
  if(rv <= 0) return -1;
  f->nread += rv;

  while(f->nread>0) {
    uint32_t body_available;
    int body_start;
    body_start = parse_message_headers(f->peermode,
                                       f->scratch+f->off, f->nread-f->off,
                                       f->msg);
    f->into_body = 0;
    fq_debug(FQ_DEBUG_MSG, "%d = parse(+%d, %d) -> %d\n",
            body_start, f->off, (int)f->nread-f->off,
            body_start ? (int)f->msg->payload_len : 0);
    if(body_start < 0) return -1;
    if(!body_start) {
      fq_debug(FQ_DEBUG_MSG, "incomplete message header...\n");
      memmove(f->scratch, f->scratch + f->off, f->nread - f->off);
      f->nread -= f->off;
      f->off = 0;
      return 0;
    }

    free_message_stack *tls_free_message_stack = NULL;
    int msg_stack_idx = msg_free_stack_select(f->msg->payload_len);
    if(msg_stack_idx >= 0) {
      if(tls_free_message_handle == NULL)
        tls_free_message_handle = free_message_handle_acquire();
      if(tls_free_message_handle->stacks[msg_stack_idx] == NULL) {
        /* lazy create/init the cleanup stack */
        tls_free_message_handle->stacks[msg_stack_idx] = malloc(sizeof(free_message_stack));
        fq_init_free_message_stack(tls_free_message_handle->stacks[msg_stack_idx],
                                   FREE_MSG_LIST_SIZE/(1 << (msg_stack_idx + MSG_FREE_BASE)),
                                   (1 << (msg_stack_idx + MSG_FREE_BASE)));
      }
      tls_free_message_stack = tls_free_message_handle->stacks[msg_stack_idx];
    }

    if(tls_free_message_stack) {
      /* We have a message... or the formal beginnings of one */
      f->copy = fq_pop_free_message_stack(tls_free_message_stack);
      if (f->copy == NULL) {
        /* ran out of entries in free list */
        f->copy = fq_msg_alloc_BLANK(tls_free_message_stack->alloc_size);
        if (f->copy == NULL) {
          /* this is bad, we can't alloc */
          fq_debug(FQ_DEBUG_MSG, "unable to malloc, OOM?\n");
          return -1;
        }
      }

      /* always 1 as this msg only lives until it's copied by a worker thread */
      memcpy(f->copy, f->msg, sizeof(fq_msg));
      f->copy->refcnt = 1;
      f->copy->free_fn = fq_free_msg_fn;

    } else {
      f->copy = fq_msg_alloc_BLANK(CAPPED(f->msg->payload_len));
      if (f->copy == NULL) {
        /* this is bad, we can't alloc */
        fq_debug(FQ_DEBUG_MSG, "unable to malloc, OOM?\n");
        return -1;
      }

      memcpy(f->copy, f->msg, sizeof(fq_msg));
      f->copy->refcnt = 1;
      f->copy->free_fn = NULL;
    }

    /* assign the cleanup stack for this message */
    f->copy->cleanup_handle = tls_free_message_stack ? tls_free_message_handle : NULL;
    memset(&f->copy->cleanup_stack_entry, 0, sizeof(ck_stack_entry_t));

    f->off += body_start;
    body_available = f->nread - f->off;
    if(f->copy->payload_len < body_available) body_available = f->copy->payload_len;
    memcpy(f->copy->payload, f->scratch+f->off, CAPPED(body_available));
    if(body_available == f->copy->payload_len) {
      f->off += body_available;
     message_done:
      f->copy->refcnt = 1;
      f->copy->payload_len = CAPPED(f->copy->payload_len);
      fq_debug(FQ_DEBUG_MSG, "message read... injecting\n");
      f->copy->arrival_time = fq_gethrtime();
      f_msg_handler(closure, f->copy);
      f->copy = NULL;
      memset(f->msg, 0, sizeof(fq_msg));
      /* It is still allocated and we are the sole owner, refcnt must be 1 */
      f->msg->refcnt = 1;
    }
    else {
      f->nread = 0;
      f->off = 0;
      f->into_body = body_available;
      fq_debug(FQ_DEBUG_MSG, "incomplete message... (%d needed)\n",
             (int)f->msg->payload_len - (int)f->into_body);
      return 0;
    }
  }
  return 0;
}