I've taken mod_gsoap out of it and implemented my own, bare-bones
module.
The code for the module is this:
#include "stdafx.h"
#include "helloworld.h"
#include "stdafx.h"
#if !defined(__GNUC__) || __GNUC__ < 2 || \
(__GNUC__ == 2 && __GNUC_MINOR__ < 7) ||\
defined(NEXT)
#ifndef __attribute__
#define __attribute__(__x)
#endif
#endif
#include <stdio.h>
#include <assert.h>
#include "winsock2.h"
#include "apr_strings.h"
#include "apr_fnmatch.h"
#include "apr_strings.h"
#include "apr_lib.h"
#include "apr_pools.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include "httpd.h"
#include "http_request.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_main.h"
#include "http_protocol.h"
#include "http_request.h"
#include "util_script.h"
#include <httpd.h>
void testThread2(void* input)
{
printf("Sample module: Another thread being launching -
%d\n",GetCurrentThreadId());
return;
}
void testThread(void* input)
{
while(1)
{
printf("Sample module, launching thread.\n");
_beginthread(testThread2,0,NULL);
Sleep(5000);
}
return;
}
static int helloworld_handler(request_rec *r) {
/* First, some housekeeping. */
if (!r->handler || strcasecmp(r->handler, "helloworld") != 0) {
/* r->handler wasn't "helloworld", so it's none of our business */
return DECLINED;
}
if (r->method_number != M_GET) {
/* We only accept GET and HEAD requests.
* They are identical for the purposes of a content generator
* Returning an HTTP error code causes Apache to return an
* error page (ErrorDocument) to the client.
*/
return HTTP_METHOD_NOT_ALLOWED;
}
/* OK, we're happy with this request, so we'll return the response. */
ap_set_content_type(r, "text/html");
ap_rputs("<title>Hello World!</title> .... etc...starting threads...",
r);
_beginthread(testThread,0,NULL);
/* we return OK to indicate that we have successfully processed
* the request. No further processing is required.
*/
return OK;
}
static void helloworld_hooks(apr_pool_t *pool) {
/* hook helloworld_handler in to Apache */
ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA helloworld_module = {
STANDARD20_MODULE_STUFF,
NULL, /* per-directory config creator */
NULL, /* dir config merger */
NULL, /* server config creator */
NULL, /* server config merger */
NULL, /* command table */
helloworld_hooks, /*hooks */
};
Once I hit http://localhost:8080/helloworld in my browser the thread
handle leak starts.
This is evident by the output:
C:\Program Files\Apache Software Foundation\Apache2.2\bin>httpd.exe -X
Sample module, launching thread.
Sample module: Another thread being launching - 15156
Sample module, launching thread.
Sample module: Another thread being launching - 15712
Sample module, launching thread.
Sample module: Another thread being launching - 16300
Sample module, launching thread.
Sample module: Another thread being launching - 16372
Sample module, launching thread.
Sample module: Another thread being launching - 16912
Sample module, launching thread.
Sample module: Another thread being launching - 13972
Sample module, launching thread.
Sample module: Another thread being launching - 13980
Sample module, launching thread.
Sample module: Another thread being launching - 14528
Sample module, launching thread.
Sample module: Another thread being launching - 17488
Sample module, launching thread.
Sample module: Another thread being launching - 17508
C:\>handle -a -p 13112 | find "15156"
310: Thread httpd.exe(13112): 15156
If I comment out the mod_ssl module:
C:\Program Files\Apache Software Foundation\Apache2.2\bin>httpd.exe -X
Sample module, launching thread.
Sample module: Another thread being launching - 33200
Sample module, launching thread.
Sample module: Another thread being launching - 33832
Sample module, launching thread.
Sample module: Another thread being launching - 34348
Sample module, launching thread.
Sample module: Another thread being launching - 34352
Sample module, launching thread.
Sample module: Another thread being launching - 34900
Sample module, launching thread.
C:\>handle -a -p 32212 | find "33200"
It clearly is 'freed' correctly.
Does anybody have any ideas. I don't see any 'hooks' in OpenSSL for
thread creation or destruction, but maybe I'm missing something. (Yes,
I have used the APR thread functions to no avail as well).
I'm really perplexed by the behavior.
--Beau
-----Original Message-----
From: Croteau, Beau [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 14, 2007 11:59 AM
To: [email protected]
Subject: RE: Apache Thread Creation/Destroy Problem
The thread is created inside of the gsoap_handler. Though these threads
aren't necessarily mapped to a one to one gsoap_handler call. We have a
web service 'startup' function that creates several background threads
to do the processing and from there don't necessary have to have the
gsoap_handler called again for the thread leak to start happening.
--Beau
-----Original Message-----
From: Joe Lewis [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 14, 2007 11:59 AM
To: [email protected]
Subject: Re: Apache Thread Creation/Destroy Problem
Croteau, Beau wrote:
> I'm sorry, I don't understand the question.
>
> Mod_gsoap hooks in as such:
> static void
> gsoap_hooks(apr_pool_t * p)
> {
> // I think this is the call to make to register a handler for
method
> calls (GET PUT et. al.).
> // We will ask to be last so that the comment has a higher
tendency
> to
> // go at the end.
> ap_hook_handler(gsoap_handler, NULL, NULL, APR_HOOK_LAST);
>
> //Register a handler for post config processing
> ap_hook_post_config(gsoap_init, NULL, NULL, APR_HOOK_MIDDLE);
> }
>
[snip]
I think we need to know if you create the thread in the gsoap_init
function or the gsoap_handler function (not a copy of the register_hooks
function, but which hook that register_hooks uses to create the thread).
Joe