source: sources/src/cgiFastServer.cc @ 1473:8784c4181a22

Revision 1473:8784c4181a22, 4.7 KB checked in by niam, 21 months ago (diff)

[fcgi] use pc::execution module rather than using pthreads/anything directly

Line 
1/***************************************************************************
2 *            cgiFastServer.cc
3 *
4 *  Sat Aug  5 2006
5 *  Copyright  2006  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef FASTCGI_EXT
33#include <fcgiapp.h>
34
35#include "cgiFastRequest.inline"
36
37#include <libdodo/cgiFastServer.h>
38#include <libdodo/types.h>
39#include <libdodo/pcExecutionThread.h>
40#include <libdodo/pcExecutionManager.h>
41#include <libdodo/cgiFastServerEx.h>
42#include <libdodo/cgiFastExchange.h>
43#include <libdodo/pcSyncThread.h>
44#include <libdodo/pcSyncStack.h>
45
46using namespace dodo::cgi::fast;
47
48dodo::pc::sync::thread server::accept;
49
50//-------------------------------------------------------------------
51
52dodo::pc::sync::thread server::request;
53
54//-------------------------------------------------------------------
55
56void
57dummyfastCGIThread(dodo::cgi::exchange &)
58{
59}
60
61//-------------------------------------------------------------------
62
63dodo::cgi::server::handler server::handler = &dummyfastCGIThread;
64
65//-------------------------------------------------------------------
66
67server::server(server &)
68{
69}
70
71//-------------------------------------------------------------------
72
73server::server(unsigned long a_limit,
74               bool          threading,
75               unsigned int  threadsNum) : threading(threading),
76                                           threadsNum(threadsNum)
77{
78    limit = a_limit;
79
80    FCGX_Init();
81}
82
83//-------------------------------------------------------------------
84
85server::~server()
86{
87    FCGX_Finish();
88}
89
90//-------------------------------------------------------------------
91
92int
93server::thread(void *data)
94{
95    FCGX_Request req;
96    __request__ request = &req;
97
98    FCGX_InitRequest(request.request, 0, 0);
99
100    exchange cfSTD(request);
101
102    unsigned long limit = *(unsigned long *)data;
103    unsigned long requests = 0;
104
105    int res = 0;
106
107    while (true) {
108        if (limit != 0) {
109            pc::sync::stack p(&server::request);
110
111            ++requests;
112
113            if (requests >= limit)
114                break;
115        }
116
117        accept.acquire();
118        res = FCGX_Accept_r(request.request);
119        accept.release();
120
121        if (res == -1)
122            dodo_throw exception::basic(exception::MODULE_CGIFASTSERVER, SERVEREX_STACKTHREAD, exception::ERRNO_LIBDODO, SERVEREX_ACCEPTFAILED, CGIFASTSERVEREX_ACCEPTFAILED_STR, __LINE__, __FILE__);
123
124        handler(cfSTD);
125
126        FCGX_Finish_r(request.request);
127    }
128
129    return 0;
130}
131
132//-------------------------------------------------------------------
133
134void
135server::serve(cgi::server::handler func)
136{
137    if (!isFastCgi())
138        dodo_throw exception::basic(exception::MODULE_CGIFASTSERVER, SERVEREX_LISTEN, exception::ERRNO_LIBDODO, SERVEREX_ISCGI, CGIFASTSERVEREX_ISCGI_STR, __LINE__, __FILE__);
139
140    handler = func;
141
142    if (threading) {
143        pc::execution::manager m;
144
145        for (unsigned int i = 0; i < threadsNum; ++i)
146            m.run(m.add(pc::execution::thread(server::thread, &limit, pc::execution::ON_DESTRUCTION_STOP, false)));
147
148        m.wait();
149    } else {
150        unsigned long requests = 0;
151
152        FCGX_Request req;
153        __request__ request = &req;
154
155        FCGX_InitRequest(request.request, 0, 0);
156
157        exchange cfSTD(request);
158
159        while (true) {
160            if (limit != 0) {
161                ++requests;
162
163                if (requests >= limit)
164                    break;
165            }
166
167            if (FCGX_Accept_r(request.request) == -1)
168                dodo_throw exception::basic(exception::MODULE_CGIFASTSERVER, SERVEREX_LISTEN, exception::ERRNO_LIBDODO, SERVEREX_ACCEPTFAILED, CGIFASTSERVEREX_ACCEPTFAILED_STR, __LINE__, __FILE__);
169
170            handler(cfSTD);
171
172            FCGX_Finish_r(request.request);
173        }
174    }
175}
176
177//-------------------------------------------------------------------
178
179bool
180server::isFastCgi()
181{
182    return !FCGX_IsCGI();
183}
184#endif
185
186//-------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.