Ejemplo n.º 1
0
int
main (int argc, char *const *argv)
{
  int i;
  time_t start_t, end_t;
  int result = 0;
  MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *test_func)(void* data);
#ifdef MHD_WINSOCK_SOCKETS
  WORD ver_req;
  WSADATA wsa_data;
  int err;
#endif /* MHD_WINSOCK_SOCKETS */
  bool test_poll;

  test_poll = has_in_name(argv[0], "_poll");
  if (!test_poll)
    test_func = &select_thread;
  else
    {
#ifndef HAVE_POLL
      return 77;
#else  /* ! HAVE_POLL */
      test_func = &poll_thread;
#endif /* ! HAVE_POLL */
    }

#ifdef MHD_WINSOCK_SOCKETS
  ver_req = MAKEWORD(2, 2);

  err = WSAStartup(ver_req, &wsa_data);
  if (err != 0 || MAKEWORD(2, 2) != wsa_data.wVersion)
    {
      printf("WSAStartup() failed\n");
      WSACleanup();
      return 99;
    }
#endif /* MHD_WINSOCK_SOCKETS */

  /* try several times to ensure that accidental incoming connection
   * didn't interfere with test results
   */
  for (i = 0; i < 5 && result == 0; i++)
    {
      MHD_thread_handle_ sel_thrd;
      /* fprintf(stdout, "Creating, binding and listening socket...\n"); */
      MHD_socket listen_socket = start_socket_listen (AF_INET);
      if (MHD_INVALID_SOCKET == listen_socket)
        return 99;

      check_err = !0;
      /* fprintf (stdout, "Starting select() thread...\n"); */
#if defined(MHD_USE_POSIX_THREADS)
      if (0 != pthread_create (&sel_thrd, NULL, test_func, &listen_socket))
        {
          MHD_socket_close_chk_ (listen_socket);
          fprintf (stderr, "Can't start thread\n");
          return 99;
        }
#elif defined(MHD_USE_W32_THREADS)
      sel_thrd = (HANDLE)_beginthreadex (NULL, 0, test_func, &listen_socket, 0, NULL);
      if (0 == (sel_thrd))
        {
          MHD_socket_close_chk_ (listen_socket);
          fprintf (stderr, "Can't start select() thread\n");
          return 99;
        }
#else
#error No threading lib available
#endif
      /* fprintf (stdout, "Waiting...\n"); */
      local_sleep(1); /* make sure that select() is started */

      /* fprintf (stdout, "Shutting down socket...\n"); */
      start_t = time (NULL);
      shutdown (listen_socket, SHUT_RDWR);

      /* fprintf (stdout, "Waiting for thread to finish...\n"); */
      if (!MHD_join_thread_(sel_thrd))
        {
          MHD_socket_close_chk_(listen_socket);
          fprintf (stderr, "Can't join select() thread\n");
          return 99;
        }
      if (check_err)
        {
          MHD_socket_close_chk_(listen_socket);
          fprintf (stderr, "Error in waiting thread\n");
          return 99;
        }
      end_t = time (NULL);
      /* fprintf (stdout, "Thread finished.\n"); */
      MHD_socket_close_chk_(listen_socket);

      if (start_t == (time_t)-1 || end_t == (time_t)-1)
        {
          MHD_socket_close_chk_(listen_socket);
          fprintf (stderr, "Can't get current time\n");
          return 99;
        }
      if (end_t - start_t > 3)
        result++;
    }

#ifdef MHD_WINSOCK_SOCKETS
  WSACleanup();
#endif /* MHD_WINSOCK_SOCKETS */

  return result;
}
Ejemplo n.º 2
0
/**
 * Shutdown and destroy an HTTP daemon.
 *
 * @param daemon daemon to stop
 * @ingroup event
 */
void
MHD_daemon_destroy (struct MHD_Daemon *daemon)
{
  MHD_socket fd;

  daemon->shutdown = true;
  if (daemon->was_quiesced)
    fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
  else
    fd = daemon->listen_socket;

  /* FIXME: convert from here to microhttpd2-style API! */

  if (NULL != daemon->worker_pool)
    { /* Master daemon with worker pool. */
      stop_workers (daemon);
    }
  else
    {
      mhd_assert (0 == daemon->worker_pool_size);
      /* Worker daemon or single-thread daemon. */
      if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode)
        {
	  /* Worker daemon or single daemon with internal thread(s). */
	  /* Separate thread(s) is used for polling sockets. */
	  if (MHD_ITC_IS_VALID_(daemon->itc))
	    {
	      if (! MHD_itc_activate_ (daemon->itc,
				       "e"))
		MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
	    }
	  else
	    {
#ifdef HAVE_LISTEN_SHUTDOWN
	      if (MHD_INVALID_SOCKET != fd)
		{
		  if (NULL == daemon->master)
		    (void) shutdown (fd,
				     SHUT_RDWR);
		}
	      else
#endif /* HAVE_LISTEN_SHUTDOWN */
		mhd_assert (false); /* Should never happen */
	    }

	  if (! MHD_join_thread_ (daemon->pid.handle))
	    {
	      MHD_PANIC (_("Failed to join a thread\n"));
	    }
	  /* close_all_connections() was called in daemon thread. */
	}
      else
        {
          /* No internal threads are used for polling sockets
	     (external event loop) */
          MHD_daemon_close_all_connections_ (daemon);
        }
      if (MHD_ITC_IS_VALID_ (daemon->itc))
        MHD_itc_destroy_chk_ (daemon->itc);

#ifdef EPOLL_SUPPORT
      if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
           (-1 != daemon->epoll_fd) )
        MHD_socket_close_chk_ (daemon->epoll_fd);
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
      if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
           (-1 != daemon->epoll_upgrade_fd) )
        MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
#endif /* EPOLL_SUPPORT */

      MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
    }

  if (NULL != daemon->master)
    return;
  /* Cleanup that should be done only one time in master/single daemon.
   * Do not perform this cleanup in worker daemons. */

  if (MHD_INVALID_SOCKET != fd)
    MHD_socket_close_chk_ (fd);

  /* TLS clean up */
#ifdef HTTPS_SUPPORT
  if (NULL != daemon->tls_api)
    {
#if FIXME_TLS_API
      if (daemon->have_dhparams)
	{
	  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
	  daemon->have_dhparams = false;
	}
      gnutls_priority_deinit (daemon->priority_cache);
      if (daemon->x509_cred)
	gnutls_certificate_free_credentials (daemon->x509_cred);
#endif
    }
#endif /* HTTPS_SUPPORT */

#ifdef DAUTH_SUPPORT
  free (daemon->nnc);
  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
#endif
  MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
  free (daemon);
}