Comment about accept serialization
[catagits/fcgi2.git] / examples / threaded.c
1 /*
2  * threaded.c -- A simple multi-threaded FastCGI application.
3  */
4
5 #ifndef lint
6 static const char rcsid[] = "$Id: threaded.c,v 1.4 1999/08/02 18:11:50 roberts Exp $";
7 #endif /* not lint */
8
9 #include "fcgi_config.h"
10
11 #include <pthread.h>
12
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16
17 #ifdef _WIN32
18 #include <process.h>
19 #endif
20
21 #include "fcgiapp.h"
22
23
24 #define THREAD_COUNT 20
25
26 static int counts[THREAD_COUNT];
27
28 static void *doit(void *a)
29 {
30     int rc, i, thread_id = (int)a;
31     pid_t pid = getpid();
32     FCGX_Request request;
33     FCGX_Stream *in, *out, *err;
34     FCGX_ParamArray envp;
35     char *server_name;
36
37     FCGX_InitRequest(&request);
38
39     for (;;)
40     {
41         static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
42         static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER;
43
44         /* Some platforms require accept() serialization, some don't.. */
45         pthread_mutex_lock(&accept_mutex);
46         rc = FCGX_Accept_r(&in, &out, &err, &envp, &request);
47         pthread_mutex_unlock(&accept_mutex);
48
49         if (rc < 0)
50             break;
51
52         server_name = FCGX_GetParam("SERVER_NAME", envp);
53
54         FCGX_FPrintF(out,
55             "Content-type: text/html\r\n"
56             "\r\n"
57             "<title>FastCGI Hello! (multi-threaded C, fcgiapp library)</title>"
58             "<h1>FastCGI Hello! (multi-threaded C, fcgiapp library)</h1>"
59             "Thread %d, Process %ld<p>"
60             "Request counts for %d threads running on host <i>%s</i><p><code>",
61             thread_id, pid, THREAD_COUNT, server_name ? server_name : "?");
62
63         sleep(2);
64
65         pthread_mutex_lock(&counts_mutex);
66         ++counts[thread_id];
67         for (i = 0; i < THREAD_COUNT; i++)
68             FCGX_FPrintF(out, "%5d " , counts[i]);
69         pthread_mutex_unlock(&counts_mutex);
70
71         FCGX_Finish_r(&request);
72     }
73
74     return NULL;
75 }
76
77 int main(void)
78 {
79     int i;
80     pthread_t id[THREAD_COUNT];
81
82     FCGX_Init();
83
84     for (i = 1; i < THREAD_COUNT; i++)
85         pthread_create(&id[i], NULL, doit, (void*)i);
86
87     doit(0);
88
89     exit(0);
90 }
91