Ejemplo n.º 1
0
/* If nsp_new returned success, you must free the nsp when you are
   done with it to conserve memory (and in some cases, sockets).
   After this call, nsp may no longer be used.  Any pending events are
   sent an NSE_STATUS_KILL callback and all outstanding iods are
   deleted. */
void nsp_delete(nsock_pool ms_pool) {
  mspool *nsp = (mspool *) ms_pool;
   gh_list *event_lists[] = { &nsp->evl.connect_events,
                               &nsp->evl.read_events,
                               &nsp->evl.write_events,
                               &nsp->evl.timer_events,
                               0
                             };
   int current_list_idx;
   msevent *nse;
   msiod *nsi;
   gh_list_elem *current, *next;

   assert(nsp);


  /* First I go through all the events sending NSE_STATUS_KILL */
    /* foreach list */
    for(current_list_idx = 0; event_lists[current_list_idx] != NULL;
	current_list_idx++) {
      while(GH_LIST_COUNT(event_lists[current_list_idx]) > 0) {
	nse = (msevent *) gh_list_pop(event_lists[current_list_idx]);
	nse->status = NSE_STATUS_KILL;
	nsock_trace_handler_callback(nsp, nse);
	nse->handler(nsp, nse, nse->userdata);
	if (nse->iod) {
	  nse->iod->events_pending--;
	  assert(nse->iod->events_pending >= 0);
	}
	msevent_delete(nsp, nse);
      }      
      gh_list_free(event_lists[current_list_idx]);
    }

  /* Then I go through and kill the iods */
    for(current = GH_LIST_FIRST_ELEM(&nsp->active_iods);
	current != NULL; current = next) {
      next = GH_LIST_ELEM_NEXT(current);
      nsi = (msiod *) GH_LIST_ELEM_DATA(current);
      nsi_delete(nsi, NSOCK_PENDING_ERROR);
    }

    /* Now we free all the memory in the free iod list */
    while((nsi = (msiod *) gh_list_pop(&nsp->free_iods))) {
      free(nsi);
    }

    while((nsi = (msiod *) gh_list_pop(&nsp->evl.free_events))) {
      free(nsi);
    }
    gh_list_free(&nsp->evl.free_events);
    gh_list_free(&nsp->active_iods);
    gh_list_free(&nsp->free_iods);

    free(nsp);
}
Ejemplo n.º 2
0
/* Adjust various statistics, dispatches the event handler (if notify is
 * nonzero) and then deletes the event.  This function does NOT delete the event
 * from any lists it might be on (eg nsp->read_list etc.) nse->event_done
 * MUST be true when you call this */
void msevent_dispatch_and_delete(mspool *nsp, msevent *nse, int notify) {
  assert(nsp);
  assert(nse);

  assert(nse->event_done);

  nsp->events_pending--;
  assert(nsp->events_pending >= 0);

  if (nse->iod) {
    nse->iod->events_pending--;
    assert(nse->iod->events_pending >= 0);
  }

  if (notify) {
    nsock_trace_handler_callback(nsp, nse);
    nse->handler(nsp, nse, nse->userdata);
  }

  /* FIXME: We should be updating stats here ... */

  /* Now we clobber the event ... */
  msevent_delete(nsp, nse);
}
Ejemplo n.º 3
0
/* If nsp_new returned success, you must free the nsp when you are done with it
 * to conserve memory (and in some cases, sockets).  After this call, nsp may no
 * longer be used.  Any pending events are sent an NSE_STATUS_KILL callback and
 * all outstanding iods are deleted. */
void nsp_delete(nsock_pool ms_pool) {
  mspool *nsp = (mspool *)ms_pool;
  msevent *nse;
  msiod *nsi;
  int i;
  gh_list_elem *current, *next;
  gh_list *event_lists[] = {
    &nsp->connect_events,
    &nsp->read_events,
    &nsp->write_events,
    &nsp->timer_events,
#if HAVE_PCAP
    &nsp->pcap_read_events,
#endif
    NULL
  };

  assert(nsp);

  /* First I go through all the events sending NSE_STATUS_KILL */
  for (i = 0; event_lists[i] != NULL; i++) {
    while (GH_LIST_COUNT(event_lists[i]) > 0) {
      nse = (msevent *)gh_list_pop(event_lists[i]);

      assert(nse);
      nse->status = NSE_STATUS_KILL;
      nsock_trace_handler_callback(nsp, nse);
      nse->handler(nsp, nse, nse->userdata);
      if (nse->iod) {
        nse->iod->events_pending--;
        assert(nse->iod->events_pending >= 0);
      }
      msevent_delete(nsp, nse);
    }
    gh_list_free(event_lists[i]);
  }

  /* foreach msiod */
  for (current = GH_LIST_FIRST_ELEM(&nsp->active_iods); current != NULL; current = next) {
    next = GH_LIST_ELEM_NEXT(current);
    nsi = (msiod *)GH_LIST_ELEM_DATA(current);
    nsi_delete(nsi, NSOCK_PENDING_ERROR);

    gh_list_remove_elem(&nsp->active_iods, current);
    gh_list_prepend(&nsp->free_iods, nsi);
  }

  /* Now we free all the memory in the free iod list */
  while ((nsi = (msiod *)gh_list_pop(&nsp->free_iods))) {
    free(nsi);
  }

  while ((nse = (msevent *)gh_list_pop(&nsp->free_events))) {
    free(nse);
  }

  gh_list_free(&nsp->active_iods);
  gh_list_free(&nsp->free_iods);
  gh_list_free(&nsp->free_events);

  nsock_engine_destroy(nsp);

#if HAVE_OPENSSL
  if (nsp->sslctx != NULL)
    SSL_CTX_free(nsp->sslctx);
#endif

  free(nsp);
}
/* If nsp_new returned success, you must free the nsp when you are done with it
 * to conserve memory (and in some cases, sockets).  After this call, nsp may no
 * longer be used.  Any pending events are sent an NSE_STATUS_KILL callback and
 * all outstanding iods are deleted. */
void nsp_delete(nsock_pool ms_pool) {
  mspool *nsp = (mspool *)ms_pool;
  msevent *nse;
  msiod *nsi;
  int i;
  gh_lnode_t *current, *next;
  gh_list_t *event_lists[] = {
    &nsp->connect_events,
    &nsp->read_events,
    &nsp->write_events,
#if HAVE_PCAP
    &nsp->pcap_read_events,
#endif
    NULL
  };

  assert(nsp);

  /* First I go through all the events sending NSE_STATUS_KILL */
  for (i = 0; event_lists[i] != NULL; i++) {
    while (gh_list_count(event_lists[i]) > 0) {
      gh_lnode_t *lnode = gh_list_pop(event_lists[i]);

      assert(lnode);

#if HAVE_PCAP
      if (event_lists[i] == &nsp->pcap_read_events)
        nse = lnode_msevent2(lnode);
      else
#endif
        nse = lnode_msevent(lnode);

      assert(nse);

      nse->status = NSE_STATUS_KILL;
      nsock_trace_handler_callback(nsp, nse);
      nse->handler(nsp, nse, nse->userdata);

      if (nse->iod) {
        nse->iod->events_pending--;
        assert(nse->iod->events_pending >= 0);
      }
      msevent_delete(nsp, nse);
    }
    gh_list_free(event_lists[i]);
  }

  /* Kill timers too, they're not in event lists */
  while (gh_heap_count(&nsp->expirables) > 0) {
    gh_hnode_t *hnode;

    hnode = gh_heap_pop(&nsp->expirables);
    nse = container_of(hnode, msevent, expire);

    if (nse->type == NSE_TYPE_TIMER) {
      nse->status = NSE_STATUS_KILL;
      nsock_trace_handler_callback(nsp, nse);
      nse->handler(nsp, nse, nse->userdata);
      msevent_delete(nsp, nse);
      gh_list_append(&nsp->free_events, &nse->nodeq_io);
    }
  }

  gh_heap_free(&nsp->expirables);

  /* foreach msiod */
  for (current = gh_list_first_elem(&nsp->active_iods);
       current != NULL;
       current = next) {
    next = gh_lnode_next(current);
    nsi = container_of(current, msiod, nodeq);

    nsi_delete(nsi, NSOCK_PENDING_ERROR);

    gh_list_remove(&nsp->active_iods, current);
    gh_list_prepend(&nsp->free_iods, &nsi->nodeq);
  }

  /* Now we free all the memory in the free iod list */
  while ((current = gh_list_pop(&nsp->free_iods))) {
    nsi = container_of(current, msiod, nodeq);
    free(nsi);
  }

  while ((current = gh_list_pop(&nsp->free_events))) {
    nse = lnode_msevent(current);
    free(nse);
  }

  gh_list_free(&nsp->active_iods);
  gh_list_free(&nsp->free_iods);
  gh_list_free(&nsp->free_events);

  nsock_engine_destroy(nsp);

#if HAVE_OPENSSL
  if (nsp->sslctx != NULL)
    SSL_CTX_free(nsp->sslctx);
#endif

  free(nsp);
}