1748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/*
2748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     This file is part of libmicrohttpd
3748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     Copyright (C) 2013, 2015 Christian Grothoff
4748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
5748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     libmicrohttpd is free software; you can redistribute it and/or modify
6748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     it under the terms of the GNU General Public License as published
7748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     by the Free Software Foundation; either version 2, or (at your
8748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     option) any later version.
9748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
10748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     libmicrohttpd is distributed in the hope that it will be useful, but
11748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     WITHOUT ANY WARRANTY; without even the implied warranty of
12748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     General Public License for more details.
14748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
15748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     You should have received a copy of the GNU General Public License
16748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     along with libmicrohttpd; see the file COPYING.  If not, write to the
17748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     Boston, MA 02111-1307, USA.
19748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat*/
20748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/**
21748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @file test_quiesce.c
22748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @brief  Testcase for libmicrohttpd quiescing
23748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @author Christian Grothoff
24748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */
25748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
26748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "MHD_config.h"
27748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "platform.h"
28748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "platform_interface.h"
29748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <curl/curl.h>
30748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <microhttpd.h>
31748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <stdlib.h>
32748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <string.h>
33748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <time.h>
34748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/types.h>
35748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <pthread.h>
36748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
37748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef WINDOWS
38748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <unistd.h>
39748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/socket.h>
40748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
41748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
42748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
43748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#undef CPU_COUNT
44748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
45748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if !defined(CPU_COUNT)
46748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define CPU_COUNT 2
47748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
48748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
49748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
50748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstruct CBC
51748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
52748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  char *buf;
53748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  size_t pos;
54748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  size_t size;
55748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat};
56748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
57748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
58748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic size_t
59748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratcopyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
60748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
61748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct CBC *cbc = ctx;
62748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
63748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (cbc->pos + size * nmemb > cbc->size)
64748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 0;                   /* overflow */
65748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
66748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc->pos += size * nmemb;
67748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return size * nmemb;
68748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
69748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
70748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
71748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic int
72748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratahc_echo (void *cls,
73748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          struct MHD_Connection *connection,
74748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          const char *url,
75748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          const char *method,
76748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          const char *version,
77748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          const char *upload_data, size_t *upload_data_size,
78748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          void **unused)
79748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
80748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  static int ptr;
81748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  const char *me = cls;
82748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct MHD_Response *response;
83748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  int ret;
84748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
85748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != strcmp (me, method))
86748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return MHD_NO;              /* unexpected method */
87748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (&ptr != *unused)
88748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
89748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      *unused = &ptr;
90748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return MHD_YES;
91748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
92748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  *unused = NULL;
93748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  response = MHD_create_response_from_buffer (strlen (url),
94748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  				      (void *) url,
95748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat					      MHD_RESPMEM_MUST_COPY);
96748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
97748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_destroy_response (response);
98748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (ret == MHD_NO)
99748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    abort ();
100748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return ret;
101748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
102748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
103748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
104748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic void
105748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratrequest_completed (void *cls, struct MHD_Connection *connection,
106748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat		   void **con_cls, enum MHD_RequestTerminationCode code)
107748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
108748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  int *done = (int *)cls;
109748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  *done = 1;
110748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
111748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
112748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
113748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic void *
114748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratServeOneRequest(void *param)
115748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
116748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct MHD_Daemon *d;
117748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd_set rs;
118748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd_set ws;
119748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd_set es;
120748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_socket fd, max;
121748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  time_t start;
122748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct timeval tv;
123748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  int done = 0;
124748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
125748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd = (MHD_socket) (intptr_t) param;
126748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
127748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  d = MHD_start_daemon (MHD_USE_DEBUG,
128748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        1082, NULL, NULL, &ahc_echo, "GET",
129748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_OPTION_LISTEN_SOCKET, fd,
130748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_OPTION_NOTIFY_COMPLETED, &request_completed, &done,
131748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        MHD_OPTION_END);
132748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (d == NULL)
133748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return "MHD_start_daemon() failed";
134748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
135748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  start = time (NULL);
136748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  while ((time (NULL) - start < 5) && done == 0)
137748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
138748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      max = 0;
139748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      FD_ZERO (&rs);
140748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      FD_ZERO (&ws);
141748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      FD_ZERO (&es);
142748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
143748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        {
144748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          MHD_stop_daemon (d);
145748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          MHD_socket_close_(fd);
146748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          return "MHD_get_fdset() failed";
147748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        }
148748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      tv.tv_sec = 0;
149748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      tv.tv_usec = 1000;
150748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_SYS_select_ (max + 1, &rs, &ws, &es, &tv);
151748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_run (d);
152748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
153748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_stop_daemon (d);
154748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_socket_close_(fd);
155748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return NULL;
156748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
157748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
158748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
159748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic CURL *
160748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratsetupCURL (void *cbc)
161748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
162748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  CURL *c;
163748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
164748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  c = curl_easy_init ();
165748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
166748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
167748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc);
168748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
169748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, 150L);
170748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, 150L);
171748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
172748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  /* NOTE: use of CONNECTTIMEOUT without also
173748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     setting NOSIGNAL results in really weird
174748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     crashes on my system!*/
175748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
176748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
177748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return c;
178748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
179748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
180748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
181748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic int
182748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel ErattestGet (int type, int pool_count, int poll_flag)
183748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
184748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct MHD_Daemon *d;
185748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  CURL *c;
186748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  char buf[2048];
187748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct CBC cbc;
188748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  CURLcode errornum;
189748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_socket fd;
190748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  pthread_t thrd;
191748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  const char *thrdRet;
192748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
193748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc.buf = buf;
194748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc.size = 2048;
195748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc.pos = 0;
196748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (pool_count > 0) {
197748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
198748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          11080, NULL, NULL, &ahc_echo, "GET",
199748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          MHD_OPTION_THREAD_POOL_SIZE, pool_count, MHD_OPTION_END);
200748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
201748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  } else {
202748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
203748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
204748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  }
205748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (d == NULL)
206748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 1;
207748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
208748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  c = setupCURL(&cbc);
209748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
210748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (CURLE_OK != (errornum = curl_easy_perform (c)))
211748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
212748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr,
213748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat               "curl_easy_perform failed: `%s'\n",
214748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat               curl_easy_strerror (errornum));
215748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
216748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
217748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 2;
218748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
219748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
220748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (cbc.pos != strlen ("/hello_world")) {
221748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    curl_easy_cleanup (c);
222748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    MHD_stop_daemon (d);
223748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 4;
224748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  }
225748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) {
226748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    curl_easy_cleanup (c);
227748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    MHD_stop_daemon (d);
228748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 8;
229748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  }
230748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
231748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd = MHD_quiesce_daemon (d);
232748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != pthread_create(&thrd, NULL, &ServeOneRequest, (void*)(intptr_t) fd))
233748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
234748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "pthread_create failed\n");
235748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
236748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
237748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 16;
238748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
239748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
240748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc.pos = 0;
241748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (CURLE_OK != (errornum = curl_easy_perform (c)))
242748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
243748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr,
244748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat               "curl_easy_perform failed: `%s'\n",
245748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat               curl_easy_strerror (errornum));
246748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
247748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
248748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 2;
249748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
250748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
251748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != pthread_join(thrd, (void**)&thrdRet))
252748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
253748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "pthread_join failed\n");
254748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
255748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
256748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 16;
257748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
258748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (NULL != thrdRet)
259748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
260748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "ServeOneRequest() error: %s\n", thrdRet);
261748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
262748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
263748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 16;
264748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
265748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
266748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (cbc.pos != strlen ("/hello_world"))
267748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
268748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf(stderr, "%s\n", cbc.buf);
269748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
270748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
271748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_socket_close_(fd);
272748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 4;
273748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
274748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
275748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
276748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf(stderr, "%s\n", cbc.buf);
277748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
278748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
279748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_socket_close_(fd);
280748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 8;
281748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
282748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
283748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  /* at this point, the forked server quit, and the new
284748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat   * server has quiesced, so new requests should fail
285748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat   */
286748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (CURLE_OK == (errornum = curl_easy_perform (c)))
287748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
288748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      fprintf (stderr, "curl_easy_perform should fail\n");
289748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
290748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
291748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_socket_close_(fd);
292748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 2;
293748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
294748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_easy_cleanup (c);
295748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_stop_daemon (d);
296748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_socket_close_(fd);
297748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
298748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return 0;
299748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
300748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
301748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
302748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic int
303748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel ErattestExternalGet ()
304748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
305748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct MHD_Daemon *d;
306748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  CURL *c;
307748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  char buf[2048];
308748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct CBC cbc;
309748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  CURLM *multi;
310748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  CURLMcode mret;
311748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd_set rs;
312748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd_set ws;
313748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  fd_set es;
314748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_socket max;
315748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  int running;
316748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct CURLMsg *msg;
317748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  time_t start;
318748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  struct timeval tv;
319748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  int i;
320748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_socket fd;
321748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
322748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  multi = NULL;
323748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc.buf = buf;
324748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc.size = 2048;
325748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  cbc.pos = 0;
326748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  d = MHD_start_daemon (MHD_USE_DEBUG,
327748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
328748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (d == NULL)
329748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 256;
330748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  c = setupCURL(&cbc);
331748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
332748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  multi = curl_multi_init ();
333748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (multi == NULL)
334748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
335748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
336748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
337748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 512;
338748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
339748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  mret = curl_multi_add_handle (multi, c);
340748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (mret != CURLM_OK)
341748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
342748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_multi_cleanup (multi);
343748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
344748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      MHD_stop_daemon (d);
345748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      return 1024;
346748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
347748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
348748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  for (i = 0; i < 2; i++) {
349748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    start = time (NULL);
350748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    while ((time (NULL) - start < 5) && (multi != NULL))
351748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      {
352748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        max = 0;
353748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        FD_ZERO (&rs);
354748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        FD_ZERO (&ws);
355748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        FD_ZERO (&es);
356748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        curl_multi_perform (multi, &running);
357748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
358748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        if (mret != CURLM_OK)
359748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          {
360748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            curl_multi_remove_handle (multi, c);
361748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            curl_multi_cleanup (multi);
362748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            curl_easy_cleanup (c);
363748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            MHD_stop_daemon (d);
364748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            return 2048;
365748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          }
366748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
367748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          {
368748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            curl_multi_remove_handle (multi, c);
369748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            curl_multi_cleanup (multi);
370748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            curl_easy_cleanup (c);
371748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            MHD_stop_daemon (d);
372748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            return 4096;
373748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          }
374748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        tv.tv_sec = 0;
375748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        tv.tv_usec = 1000;
376748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        select (max + 1, &rs, &ws, &es, &tv);
377748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        curl_multi_perform (multi, &running);
378748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        if (running == 0)
379748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          {
380748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            msg = curl_multi_info_read (multi, &running);
381748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            if (msg == NULL)
382748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat              break;
383748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat            if (msg->msg == CURLMSG_DONE)
384748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat              {
385748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                if (i == 0 && msg->data.result != CURLE_OK)
386748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                  printf ("%s failed at %s:%d: `%s'\n",
387748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          "curl_multi_perform",
388748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          __FILE__,
389748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          __LINE__, curl_easy_strerror (msg->data.result));
390748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                else if (i == 1 && msg->data.result == CURLE_OK)
391748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                  printf ("%s should have failed at %s:%d\n",
392748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          "curl_multi_perform",
393748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          __FILE__,
394748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                          __LINE__);
395748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                curl_multi_remove_handle (multi, c);
396748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                curl_multi_cleanup (multi);
397748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                curl_easy_cleanup (c);
398748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                c = NULL;
399748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat                multi = NULL;
400748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat              }
401748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat          }
402748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        MHD_run (d);
403748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      }
404748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
405748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      if (i == 0) {
406748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        /* quiesce the daemon on the 1st iteration, so the 2nd should fail */
407748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        fd = MHD_quiesce_daemon(d);
408748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat	if (MHD_INVALID_SOCKET == fd)
409748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat	  abort ();
410748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat	MHD_socket_close_ (fd);
411748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        c = setupCURL (&cbc);
412748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        multi = curl_multi_init ();
413748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat        mret = curl_multi_add_handle (multi, c);
414748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      }
415748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
416748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (multi != NULL)
417748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
418748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_multi_remove_handle (multi, c);
419748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_easy_cleanup (c);
420748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      curl_multi_cleanup (multi);
421748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
422748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  MHD_stop_daemon (d);
423748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (cbc.pos != strlen ("/hello_world"))
424748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 8192;
425748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
426748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 16384;
427748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return 0;
428748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
429748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
430748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
431748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratint
432748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratmain (int argc, char *const *argv)
433748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{
434748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  unsigned int errorCount = 0;
435748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
436748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
437748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    return 2;
438748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 0, 0);
439748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION, 0, 0);
440748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  errorCount += testGet (MHD_USE_SELECT_INTERNALLY, CPU_COUNT, 0);
441748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  errorCount += testExternalGet ();
442748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
443748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
444748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      errorCount += testGet(MHD_USE_SELECT_INTERNALLY, 0, MHD_USE_POLL);
445748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION, 0, MHD_USE_POLL);
446748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      errorCount += testGet (MHD_USE_SELECT_INTERNALLY, CPU_COUNT, MHD_USE_POLL);
447748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
448748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
449748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    {
450748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 0, MHD_USE_EPOLL_LINUX_ONLY);
451748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat      errorCount += testGet (MHD_USE_SELECT_INTERNALLY, CPU_COUNT, MHD_USE_EPOLL_LINUX_ONLY);
452748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    }
453748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  if (errorCount != 0)
454748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat    fprintf (stderr, "Error (code: %u)\n", errorCount);
455748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  curl_global_cleanup ();
456748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat  return errorCount != 0;       /* 0 == pass */
457748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat}
458