예제 #1
0
파일: object.c 프로젝트: MZDN/qpid-proton
static void test_list_refcount(size_t capacity)
{
  void *one = pn_class_new(PN_OBJECT, 0);
  void *two = pn_class_new(PN_OBJECT, 0);
  void *three = pn_class_new(PN_OBJECT, 0);
  void *four = pn_class_new(PN_OBJECT, 0);

  pn_list_t *list = pn_list(PN_OBJECT, 0);
  assert(!pn_list_add(list, one));
  assert(!pn_list_add(list, two));
  assert(!pn_list_add(list, three));
  assert(!pn_list_add(list, four));
  assert(pn_list_get(list, 0) == one);
  assert(pn_list_get(list, 1) == two);
  assert(pn_list_get(list, 2) == three);
  assert(pn_list_get(list, 3) == four);
  assert(pn_list_size(list) == 4);

  assert(pn_refcount(one) == 2);
  assert(pn_refcount(two) == 2);
  assert(pn_refcount(three) == 2);
  assert(pn_refcount(four) == 2);

  pn_list_del(list, 1, 2);
  assert(pn_list_size(list) == 2);

  assert(pn_refcount(one) == 2);
  assert(pn_refcount(two) == 1);
  assert(pn_refcount(three) == 1);
  assert(pn_refcount(four) == 2);

  assert(pn_list_get(list, 0) == one);
  assert(pn_list_get(list, 1) == four);

  assert(!pn_list_add(list, one));

  assert(pn_list_size(list) == 3);
  assert(pn_refcount(one) == 3);

  pn_decref(list);

  assert(pn_refcount(one) == 1);
  assert(pn_refcount(two) == 1);
  assert(pn_refcount(three) == 1);
  assert(pn_refcount(four) == 1);

  pn_decref(one);
  pn_decref(two);
  pn_decref(three);
  pn_decref(four);
}
예제 #2
0
void pn_selector_add(pn_selector_t *selector, pn_selectable_t *selectable)
{
  assert(selector);
  assert(selectable);
  assert(pni_selectable_get_index(selectable) < 0);
  pn_socket_t sock = pn_selectable_get_fd(selectable);
  iocpdesc_t *iocpd = NULL;

  if (pni_selectable_get_index(selectable) < 0) {
    pn_list_add(selector->selectables, selectable);
    pn_list_add(selector->iocp_descriptors, NULL);
    size_t size = pn_list_size(selector->selectables);
    pni_selectable_set_index(selectable, size - 1);
  }

  pn_selector_update(selector, selectable);
}
예제 #3
0
파일: transform.c 프로젝트: sdnnfv/qpid
void pn_transform_rule(pn_transform_t *transform, const char *pattern,
                       const char *substitution)
{
    assert(transform);
    pn_rule_t *rule = pn_rule(pattern, substitution);
    pn_list_add(transform->rules, rule);
    pn_decref(rule);
}
예제 #4
0
파일: object.c 프로젝트: MZDN/qpid-proton
static void test_list(size_t capacity)
{
  pn_list_t *list = pn_list(PN_WEAKREF, 0);
  assert(pn_list_size(list) == 0);
  assert(!pn_list_add(list, (void *) 0));
  assert(!pn_list_add(list, (void *) 1));
  assert(!pn_list_add(list, (void *) 2));
  assert(!pn_list_add(list, (void *) 3));
  assert(pn_list_get(list, 0) == (void *) 0);
  assert(pn_list_get(list, 1) == (void *) 1);
  assert(pn_list_get(list, 2) == (void *) 2);
  assert(pn_list_get(list, 3) == (void *) 3);
  assert(pn_list_size(list) == 4);
  pn_list_del(list, 1, 2);
  assert(pn_list_size(list) == 2);
  assert(pn_list_get(list, 0) == (void *) 0);
  assert(pn_list_get(list, 1) == (void *) 3);
  pn_decref(list);
}
예제 #5
0
pn_connection_t *pn_reactor_connection(pn_reactor_t *reactor, pn_handler_t *handler) {
  assert(reactor);
  pn_connection_t *connection = pn_connection();
  pn_record_t *record = pn_connection_attachments(connection);
  pn_record_set_handler(record, handler);
  pn_connection_collect(connection, pn_reactor_collector(reactor));
  pn_list_add(pn_reactor_children(reactor), connection);
  pni_record_init_reactor(record, reactor);
  pn_decref(connection);
  return connection;
}
예제 #6
0
파일: iocp.c 프로젝트: JemDay/qpid-proton
static pn_list_t *iocp_map_close_all(iocp_t *iocp)
{
  // Zombify stragglers, i.e. no pn_close() from the application.
  pn_list_t *externals = pn_list(PN_OBJECT, 0);
  for (pn_handle_t entry = pn_hash_head(iocp->iocpdesc_map); entry;
       entry = pn_hash_next(iocp->iocpdesc_map, entry)) {
    iocpdesc_t *iocpd = (iocpdesc_t *) pn_hash_value(iocp->iocpdesc_map, entry);
    // Just listeners first.
    if (is_listener(iocpd)) {
      if (iocpd->external) {
        // Owned by application, just keep a temporary reference to it.
        // iocp_result_t structs must not be free'd until completed or
        // the completion port is closed.
        if (iocpd->ops_in_progress)
          pn_list_add(externals, iocpd);
        pni_iocpdesc_map_del(iocp, iocpd->socket);
      } else {
        // Make it a zombie.
        pni_iocp_begin_close(iocpd);
      }
    }
  }
  pni_iocp_drain_completions(iocp);

  for (pn_handle_t entry = pn_hash_head(iocp->iocpdesc_map); entry;
       entry = pn_hash_next(iocp->iocpdesc_map, entry)) {
    iocpdesc_t *iocpd = (iocpdesc_t *) pn_hash_value(iocp->iocpdesc_map, entry);
    if (iocpd->external) {
      iocpd->read_closed = true;   // Do not consume from read side
      iocpd->write_closed = true;  // Do not shutdown write side
      if (iocpd->ops_in_progress)
        pn_list_add(externals, iocpd);
      pni_iocpdesc_map_del(iocp, iocpd->socket);
    } else {
      // Make it a zombie.
      pni_iocp_begin_close(iocpd);
    }
  }
  return externals;
}
예제 #7
0
파일: object.c 프로젝트: MZDN/qpid-proton
void test_list_compare(void)
{
  pn_list_t *a = pn_list(PN_OBJECT, 0);
  pn_list_t *b = pn_list(PN_OBJECT, 0);

  assert(pn_equals(a, b));

  void *one = pn_class_new(PN_OBJECT, 0);
  void *two = pn_class_new(PN_OBJECT, 0);
  void *three = pn_class_new(PN_OBJECT, 0);

  pn_list_add(a, one);
  assert(!pn_equals(a, b));
  pn_list_add(b, one);
  assert(pn_equals(a, b));

  pn_list_add(b, two);
  assert(!pn_equals(a, b));
  pn_list_add(a, two);
  assert(pn_equals(a, b));

  pn_list_add(a, three);
  assert(!pn_equals(a, b));
  pn_list_add(b, three);
  assert(pn_equals(a, b));

  pn_free(a); pn_free(b);
  pn_free(one); pn_free(two); pn_free(three);
}
예제 #8
0
파일: list.c 프로젝트: MZDN/qpid-proton
void pn_list_minpush(pn_list_t *list, void *value)
{
  assert(list);
  pn_list_add(list, value);
  // we use one based indexing for the heap
  void **heap = list->elements - 1;
  int now = list->size;
  while (now > 1 && pn_class_compare(list->clazz, heap[now/2], value) > 0) {
    heap[now] = heap[now/2];
    now /= 2;
  }
  heap[now] = value;
}
예제 #9
0
파일: object.c 프로젝트: MZDN/qpid-proton
static void test_map_iteration(int n)
{
  pn_list_t *pairs = pn_list(PN_OBJECT, 2*n);
  for (int i = 0; i < n; i++) {
    void *key = pn_class_new(PN_OBJECT, 0);
    void *value = pn_class_new(PN_OBJECT, 0);
    pn_list_add(pairs, key);
    pn_list_add(pairs, value);
    pn_decref(key);
    pn_decref(value);
  }

  pn_map_t *map = pn_map(PN_OBJECT, PN_OBJECT, 0, 0.75);

  assert(pn_map_head(map) == 0);

  for (int i = 0; i < n; i++) {
    pn_map_put(map, pn_list_get(pairs, 2*i), pn_list_get(pairs, 2*i + 1));
  }

  for (pn_handle_t entry = pn_map_head(map); entry; entry = pn_map_next(map, entry))
  {
    void *key = pn_map_key(map, entry);
    void *value = pn_map_value(map, entry);
    ssize_t idx = pn_list_index(pairs, key);
    assert(idx >= 0);

    assert(pn_list_get(pairs, idx) == key);
    assert(pn_list_get(pairs, idx + 1) == value);

    pn_list_del(pairs, idx, 2);
  }

  assert(pn_list_size(pairs) == 0);

  pn_decref(map);
  pn_decref(pairs);
}
예제 #10
0
파일: iocp.c 프로젝트: JemDay/qpid-proton
static void complete_accept(accept_result_t *result, HRESULT status)
{
  result->new_sock->ops_in_progress--;
  iocpdesc_t *ld = result->base.iocpd;
  if (ld->read_closed) {
    if (!result->new_sock->closing)
      pni_iocp_begin_close(result->new_sock);
    free(result);    // discard
    reap_check(ld);
  } else {
    result->base.status = status;
    pn_list_add(ld->acceptor->accepts, result);
    pni_events_update(ld, ld->events | PN_READABLE);
  }
}
예제 #11
0
파일: iocp.c 프로젝트: JemDay/qpid-proton
static void zombie_list_add(iocpdesc_t *iocpd)
{
  assert(iocpd->closing);
  if (!iocpd->ops_in_progress) {
    // No need to make a zombie.
    if (iocpd->socket != INVALID_SOCKET) {
      closesocket(iocpd->socket);
      iocpd->socket = INVALID_SOCKET;
      iocpd->read_closed = true;
    }
    return;
  }
  // Allow 2 seconds for graceful shutdown before releasing socket resource.
  iocpd->reap_time = pn_i_now() + 2000;
  pn_list_add(iocpd->iocp->zombie_list, iocpd);
}
예제 #12
0
파일: iocp.c 프로젝트: JemDay/qpid-proton
static void begin_accept(pni_acceptor_t *acceptor, accept_result_t *result)
{
  if (acceptor->listen_sock->closing) {
    if (result) {
      free(result);
      acceptor->accept_queue_size--;
    }
    if (acceptor->accept_queue_size == 0)
      acceptor->signalled = true;
    return;
  }

  if (result) {
    reset_accept_result(result);
  } else {
    if (acceptor->accept_queue_size < IOCP_MAX_ACCEPTS &&
        pn_list_size(acceptor->accepts) == acceptor->accept_queue_size ) {
      result = accept_result(acceptor->listen_sock);
      acceptor->accept_queue_size++;
    } else {
      // an async accept is still pending or max concurrent accepts already hit
      return;
    }
  }

  result->new_sock = create_same_type_socket(acceptor->listen_sock);
  if (result->new_sock) {
    // Not yet connected.
    result->new_sock->read_closed = true;
    result->new_sock->write_closed = true;

    bool success = acceptor->fn_accept_ex(acceptor->listen_sock->socket, result->new_sock->socket,
                     result->address_buffer, 0, IOCP_SOCKADDRMAXLEN, IOCP_SOCKADDRMAXLEN,
                     &result->unused, (LPOVERLAPPED) result);
    if (!success && WSAGetLastError() != ERROR_IO_PENDING) {
      result->base.status = WSAGetLastError();
      pn_list_add(acceptor->accepts, result);
      pni_events_update(acceptor->listen_sock, acceptor->listen_sock->events | PN_READABLE);
    } else {
      acceptor->listen_sock->ops_in_progress++;
      // This socket is equally involved in the async operation.
      result->new_sock->ops_in_progress++;
    }
  } else {
    iocpdesc_fail(acceptor->listen_sock, WSAGetLastError(), "create accept socket");
  }
}
예제 #13
0
파일: object.c 프로젝트: MZDN/qpid-proton
static pn_list_t *build_list(size_t capacity, ...)
{
  pn_list_t *result = pn_list(PN_OBJECT, capacity);
  va_list ap;

  va_start(ap, capacity);
  while (true) {
    void *arg = va_arg(ap, void *);
    if (arg == END) {
      break;
    }

    pn_list_add(result, arg);
    pn_class_decref(PN_OBJECT, arg);
  }
  va_end(ap);

  return result;
}
예제 #14
0
static void pn_event_finalize(pn_event_t *event) {
  // decref before adding to the free list
  if (event->clazz && event->context) {
    pn_class_decref(event->clazz, event->context);
  }

  pn_list_t *pool = event->pool;

  if (pool && pn_refcount(pool) > 1) {
    event->pool = NULL;
    event->type = PN_EVENT_NONE;
    event->clazz = NULL;
    event->context = NULL;
    event->next = NULL;
    pn_record_clear(event->attachments);
    pn_list_add(pool, event);
  } else {
    pn_decref(event->attachments);
  }

  pn_decref(pool);
}
예제 #15
0
파일: object.c 프로젝트: MZDN/qpid-proton
static void test_list_index(void)
{
  pn_list_t *l = pn_list(PN_WEAKREF, 0);
  void *one = pn_string("one");
  void *two = pn_string("two");
  void *three = pn_string("three");
  void *dup1 = pn_string("dup");
  void *dup2 = pn_string("dup");
  void *last = pn_string("last");

  pn_list_add(l, one);
  pn_list_add(l, two);
  pn_list_add(l, three);
  pn_list_add(l, dup1);
  pn_list_add(l, dup2);
  pn_list_add(l, last);

  check_list_index(l, one, 0);
  check_list_index(l, two, 1);
  check_list_index(l, three, 2);
  check_list_index(l, dup1, 3);
  check_list_index(l, dup2, 3);
  check_list_index(l, last, 5);

  void *nonexistent = pn_string("nonexistent");

  check_list_index(l, nonexistent, -1);

  pn_free(l);
  pn_free(one);
  pn_free(two);
  pn_free(three);
  pn_free(dup1);
  pn_free(dup2);
  pn_free(last);
  pn_free(nonexistent);
}
예제 #16
0
void connection_dispatch(pn_handler_t *h, pn_event_t *event, pn_event_type_t type)
{
  connection_context_t *cc = connection_context(h);
  bool replying = cc->global->opts->reply;

  switch (type) {
  case PN_LINK_REMOTE_OPEN:
    {
      pn_link_t *link = pn_event_link(event);
      if (pn_link_is_receiver(link)) {
        check(cc->recv_link == NULL, "Multiple incomming links on one connection");
        cc->recv_link = link;
        pn_connection_t *conn = pn_event_connection(event);
        pn_list_add(cc->global->active_connections, conn);
        if (cc->global->shutting_down) {
          pn_connection_close(conn);
          break;
        }
        if (replying) {
          // Set up a reply link and defer granting credit to the incoming link
          pn_connection_t *conn = pn_session_connection(pn_link_session(link));
          pn_session_t *ssn = pn_session(conn);
          pn_session_open(ssn);
          char name[100]; // prefer a multiplatform uuid generator
          sprintf(name, "reply_sender_%d", cc->connection_id);
          cc->reply_link = pn_sender(ssn, name);
          pn_link_open(cc->reply_link);
        }
        else {
          pn_flowcontroller_t *fc = pn_flowcontroller(1024);
          pn_handler_add(h, fc);
          pn_decref(fc);
        }
      }
    }
    break;
  case PN_LINK_FLOW:
    {
      if (replying) {
        pn_link_t *reply_link = pn_event_link(event);
        // pn_flowcontroller handles the non-reply case
        check(reply_link == cc->reply_link, "internal error");

        // Grant the sender as much credit as just given to us for replies
        int delta = pn_link_credit(reply_link) - pn_link_credit(cc->recv_link);
        if (delta > 0)
          pn_link_flow(cc->recv_link, delta);
      }
    }
    break;
  case PN_DELIVERY:
    {
      pn_link_t *recv_link = pn_event_link(event);
      pn_delivery_t *dlv = pn_event_delivery(event);
      if (pn_link_is_receiver(recv_link) && !pn_delivery_partial(dlv)) {
        if (cc->global->received == 0) statistics_start(cc->global->stats);

        size_t encoded_size = pn_delivery_pending(dlv);
        cc->global->encoded_data = ensure_buffer(cc->global->encoded_data, encoded_size,
                                                 &cc->global->encoded_data_size);
        check(cc->global->encoded_data, "decoding buffer realloc failure");

        ssize_t n = pn_link_recv(recv_link, cc->global->encoded_data, encoded_size);
        check(n == (ssize_t) encoded_size, "message data read fail");
        pn_message_t *msg = cc->global->message;
        int err = pn_message_decode(msg, cc->global->encoded_data, n);
        check(err == 0, "message decode error");
        cc->global->received++;
        pn_delivery_settle(dlv);
        statistics_msg_received(cc->global->stats, msg);

        if (replying) {
          const char *reply_addr = pn_message_get_reply_to(msg);
          if (reply_addr) {
            pn_link_t *rl = cc->reply_link;
            check(pn_link_credit(rl) > 0, "message received without corresponding reply credit");
            LOG("Replying to: %s\n", reply_addr );

            pn_message_set_address(msg, reply_addr);
            pn_message_set_creation_time(msg, msgr_now());

            char tag[8];
            void *ptr = &tag;
            *((uint64_t *) ptr) = cc->global->sent;
            pn_delivery_t *dlv = pn_delivery(rl, pn_dtag(tag, 8));
            size_t size = cc->global->encoded_data_size;
            int err = pn_message_encode(msg, cc->global->encoded_data, &size);
            check(err == 0, "message encoding error");
            pn_link_send(rl, cc->global->encoded_data, size);
            pn_delivery_settle(dlv);

            cc->global->sent++;
          }
        }
      }
      if (cc->global->received >= cc->global->opts->msg_count) {
        global_shutdown(cc->global);
      }
    }
    break;
  case PN_CONNECTION_UNBOUND:
    {
      pn_connection_t *conn = pn_event_connection(event);
      pn_list_remove(cc->global->active_connections, conn);
      pn_connection_release(conn);
    }
    break;
  default:
    break;
  }
}
예제 #17
0
파일: list.c 프로젝트: MZDN/qpid-proton
void pn_list_fill(pn_list_t *list, void *value, int n)
{
  for (int i = 0; i < n; i++) {
    pn_list_add(list, value);
  }
}
예제 #18
0
void 
connection_dispatch ( pn_handler_t *h, pn_event_t *event, pn_event_type_t type )
{
  connection_context_t *cc = connection_context(h);

  switch ( type ) 
  {
    case PN_LINK_REMOTE_OPEN:
      {
        pn_link_t *link = pn_event_link(event);
        if (pn_link_is_receiver(link)) {
          check(cc->recv_link == NULL, "Multiple incomming links on one connection");
          cc->recv_link = link;
          pn_connection_t *conn = pn_event_connection(event);
          pn_list_add(cc->global->active_connections, conn);
          if (cc->global->shutting_down) {
            pn_connection_close(conn);
            break;
          }

          pn_flowcontroller_t *fc = pn_flowcontroller(1024);
          pn_handler_add(h, fc);
          pn_decref(fc);
        }
      }
      break;

    case PN_DELIVERY:
      {
        pn_link_t *recv_link = pn_event_link(event);
        pn_delivery_t *dlv = pn_event_delivery(event);
        if (pn_link_is_receiver(recv_link) && !pn_delivery_partial(dlv)) {
          if (cc->global->received == 0) statistics_start(cc->global->stats);

          size_t encoded_size = pn_delivery_pending(dlv);
          cc->global->encoded_data = ensure_buffer(cc->global->encoded_data, encoded_size,
                                                   &cc->global->encoded_data_size);
          check(cc->global->encoded_data, "decoding buffer realloc failure");

          /*
            If this was the first message received, 
            initialize our reporting.
          */
          if ( ! cc->global->received )
            rr_init ( & cc->global->resource_reporter );

          ssize_t n = pn_link_recv(recv_link, cc->global->encoded_data, encoded_size);
          check(n == (ssize_t) encoded_size, "message data read fail");
          //fprintf ( stderr, "MDEBUG encoded_size == %d\n", encoded_size );
          pn_message_t *msg = cc->global->message;

          int err = pn_message_decode ( msg, cc->global->encoded_data, n );
          check ( err == 0, "message decode error" );

          /* MICK -- annotate! ================================  */
           if ( cc->global->opts->timestamping )
           {
             double message_timestamp;
             if ( get_message_timestamp ( msg, & message_timestamp ) )
             {
               double now = now_timestamp ( );
               cc->global->total_latency += (now - message_timestamp);
             }
             else
             {
               fprintf ( stderr, 
                         "receiver: no timestamp at msg count %d.\n", 
                         cc->global->received 
                       );
               exit ( 1 );
             }
           }
          /* MICK -- end annotate! =============================  */


          cc->global->received++;

          /*---------------------------------------
            Do a report
          ---------------------------------------*/
          if ( ! ( cc->global->received % cc->global->opts->report_frequency ) )
          {
            static bool first_time = true;
            double cpu_percentage;
            int    rss;
            double sslr = rr_seconds_since_last_report ( & cc->global->resource_reporter );
            rr_report ( & cc->global->resource_reporter, & cpu_percentage, & rss );
            double throughput = (double)(cc->global->opts->report_frequency) / sslr;

            if ( first_time )
            {
              if ( cc->global->opts->timestamping )
	      {
		if ( cc->global->opts->print_message_size )
		  fprintf(cc->global->report_fp, "msg_size\trecv_msgs\tcpu\trss\tthroughput\tlatency\n");
		else
		  fprintf(cc->global->report_fp, "recv_msgs\tcpu\trss\tthroughput\tlatency\n");
	      }
	      else
	      {
		if ( cc->global->opts->print_message_size )
		  fprintf(cc->global->report_fp, "msg_size\trecv_msgs\tcpu\trss\tthroughput\n");
		else
		  fprintf(cc->global->report_fp, "recv_msgs\tcpu\trss\tthroughput\n");
	      }
              first_time = false;
            }

            if ( cc->global->opts->timestamping )
            {
              double average_latency = cc->global->total_latency / 
                                       cc->global->opts->report_frequency;
              average_latency *= 1000.0;  // in msec.
              cc->global->total_latency = 0;

              fprintf ( cc->global->report_fp, 
                        "%d\t%lf\t%d\t%lf\t%lf\n", 
                        cc->global->received, 
                        cpu_percentage,
                        rss,
                        throughput,
                        average_latency
                      );
            }
            else
            {
              // was: 
              // "recv_msgs: %10d   cpu: %5.1lf   rss: %6d   throughput: %8.0lf\n"
	      if ( cc->global->opts->print_message_size )
	      {
		fprintf ( cc->global->report_fp, 
			  "%d\t%d\t%lf\t%d\t%lf\n", 
			  cc->global->opts->message_size,
			  cc->global->received, 
			  cpu_percentage,
			  rss,
			  throughput
			);
	      }
	      else
	      {
		fprintf ( cc->global->report_fp, 
			  "%d\t%lf\t%d\t%lf\n", 
			  cc->global->received, 
			  cpu_percentage,
			  rss,
			  throughput
			);
	      }
            }

          }
          pn_delivery_settle(dlv); // move this up

          statistics_msg_received(cc->global->stats, msg);
        }
        if (cc->global->received >= cc->global->opts->msg_count) {
          global_shutdown(cc->global);
        }
      }
      break;

    case PN_CONNECTION_UNBOUND:
      {
        pn_connection_t *conn = pn_event_connection(event);
        pn_list_remove(cc->global->active_connections, conn);
        pn_connection_release(conn);
      }
      break;

    default:
      break;
  }
}