Is there a way for the stub/skeleton compiler to generate threaded services (i.e. by spawning a thread for each request or by thread pooling) or do I have to manually add soap_copy(), pthread_create() ...
I k开发者_如何学编程now that -- according to the FAQ and user guide 7.2.4 -- gSOAP is thread safe and does support multi-threaded services. However, using the soapcpp2 -i flag I end up with
int DummyService::run(int port)
{
if (soap_valid_socket(bind(NULL, port, 100)))
{
for (;;)
{
if (!soap_valid_socket(accept()))
return this->error;
(void)serve();
soap_destroy(this);
soap_end(this);
}
}
else
return this->error;
return SOAP_OK;
}
Any hint?
This may not be a direct treatment of your specific request, but it is as close as I could find... (clipped from http://www.cs.fsu.edu/~engelen/soapdoc2.html#sec:mt )
The following example illustrates the use of threads to improve the quality of service by handling new requests in separate threads:
#include "soapH.h"
#include < pthread.h >
#define BACKLOG (100) // Max. request backlog
int main(int argc, char **argv)
{
struct soap soap;
soap_init(&soap);
if (argc < 2) // no args: assume this is a CGI application
{
soap_serve(&soap); // serve request, one thread, CGI style
soap_destroy(&soap); // dealloc C++ data
soap_end(&soap); // dealloc data and clean up
}
else
{
soap.send_timeout = 60; // 60 seconds
soap.recv_timeout = 60; // 60 seconds
soap.accept_timeout = 3600; // server stops after 1 hour of inactivity
soap.max_keep_alive = 100; // max keep-alive sequence
void *process_request(void*);
struct soap *tsoap;
pthread_t tid;
int port = atoi(argv[1]); // first command-line arg is port
SOAP_SOCKET m, s;
m = soap_bind(&soap, NULL, port, BACKLOG);
if (!soap_valid_socket(m))
exit(1);
fprintf(stderr, "Socket connection successful %d\n", m);
for (;;)
{
s = soap_accept(&soap);
if (!soap_valid_socket(s))
{
if (soap.errnum)
{
soap_print_fault(&soap, stderr);
exit(1);
}
fprintf(stderr, "server timed out\n");
break;
}
fprintf(stderr, "Thread %d accepts socket %d connection from IP %d.%d.%d.%d\n", i, s, (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF);
tsoap = soap_copy(&soap); // make a safe copy
if (!tsoap)
break;
pthread_create(&tid, NULL, (void*(*)(void*))process_request, (void*)tsoap);
}
}
soap_done(&soap); // detach soap struct
return 0;
}
void *process_request(void *soap)
{
pthread_detach(pthread_self());
soap_serve((struct soap*)soap);
soap_destroy((struct soap*)soap); // dealloc C++ data
soap_end((struct soap*)soap); // dealloc data and clean up
soap_done((struct soap*)soap); // detach soap struct
free(soap);
return NULL;
}
Note: the code does not wait for threads to join the main thread upon program termination.
There is additional threading information in the same area of the document referenced in the link above. It may at least provide a starting place in your search for a solution.
精彩评论