Return-Path: Delivered-To: new-httpd-archive@hyperreal.org Received: (qmail 28425 invoked by uid 6000); 17 Dec 1999 03:22:43 -0000 Received: (qmail 28392 invoked from network); 17 Dec 1999 03:22:38 -0000 Received: from typhoon.mail.pipex.net (158.43.128.27) by taz.hyperreal.org with SMTP; 17 Dec 1999 03:22:38 -0000 Received: (qmail 4989 invoked from network); 17 Dec 1999 03:22:30 -0000 Received: from usercp90.uk.uudial.com (62.188.156.119) by smtp.dial.pipex.com with SMTP; 17 Dec 1999 03:22:30 -0000 From: David Whitmarsh To: new-httpd@apache.org Subject: Re: [PATCH] Re: Time to roll the 1.3.10 tarball Date: Fri, 17 Dec 1999 03:23:45 +0000 Organization: Sparkle Computer Co Ltd Message-ID: <4e6h5sgc76n743pje7rh8lenkn9kvhve4i@4ax.com> References: <008d01bf418f$b82b56c0$064b2509@raleigh.ibm.com> <9qa95s4fd61broal0kbmd91dqj3n4jo887@4ax.com> <19991215234458.C2100@pgtm0035.mch.sni.de> In-Reply-To: <19991215234458.C2100@pgtm0035.mch.sni.de> X-Mailer: Forte Agent 1.7/32.534 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="--=_16bj5s4tk2f7osiakafolaj5hi59f3n0ot.MFSBCHJLHS" Sender: new-httpd-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org Status: O ----=_16bj5s4tk2f7osiakafolaj5hi59f3n0ot.MFSBCHJLHS Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable On Wed, 15 Dec 1999 23:44:58 +0100, you wrote: >-1 on this. You cannot make changes all over the place which break >on unix, only to make it run on windows. Yes you can, but then >you must #ifdef WIN32 it. > >Like for instance... > previously, a cache file was opened (tests existance), then > its modification was derived using fstat (cheap operation because > the inode is in the buffer cache) and then the first line was > read. > > now, you stat() the file (tests existance and gets mod times), > THEN you fopen() it (but it may no longer be the same file because > another process might have unlinked() and replaced it) and > then you read the first line. This is more than about twice as > expensive as the previous solution, therefore I veto it (because > the cache has millions of files, so I DO care). > =46air enough. Easily fixed. > >And please submit the individual patches (yes, that was good) in the >correct MIME type (text/plain comes to mind, not = application/octet-stream) >to make it easier to review them. Thank you. A pleasure. > >I'm not sure how many of the patches are already in a #ifdef WIN32 >block. If they aren't, then things like TLS will be difficult (if >it compiles at all, then it will be less performant). tls is very win32 specific and is ifdef'd. gc_fix is now ifdef'd. gc_thread is ifdef'd where necessary. I don't think there is anything else in there that would affect functionality under unix child_args.patch affects a chunk of code that is already WIN32 specific. ************************************ David Whitmarsh Sparkle Computer Co Ltd Sybase C C++ perl UNIX NT ************************************ ----=_16bj5s4tk2f7osiakafolaj5hi59f3n0ot.MFSBCHJLHS Content-Type: text/plain; charset=us-ascii; name=child_args.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=child_args.patch Index: src/main/http_main.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: c:/work/repository/apache_dev/src/main/http_main.c,v retrieving revision 1.1.1.3 retrieving revision 1.1.1.3.2.3 diff -u -r1.1.1.3 -r1.1.1.3.2.3 --- http_main.c 1999/09/14 15:49:18 1.1.1.3 +++ http_main.c 1999/09/17 16:15:02 1.1.1.3.2.3 @@ -5815,7 +5815,7 @@ pCommand =3D ap_psprintf(p, "\"%s\" -Z %s -f \"%s\"", buf, = exit_event_name, ap_server_confname); =20 =20 for (i =3D 1; i < argc; i++) { - pCommand =3D ap_pstrcat(p, pCommand, " ", argv[i], NULL); + pCommand =3D ap_pstrcat(p, pCommand, " \"", argv[i], "\"", = NULL); } =20 /* Create a pipe to send socket info to the child */ ----=_16bj5s4tk2f7osiakafolaj5hi59f3n0ot.MFSBCHJLHS Content-Type: text/plain; charset=us-ascii; name=gc_fix.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=gc_fix.patch Index: src/modules/proxy/proxy_cache.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: c:/work/repository/apache_dev/src/modules/proxy/proxy_cache.c,v retrieving revision 1.1.1.3 diff -u -r1.1.1.3 proxy_cache.c --- proxy_cache.c 1999/09/14 15:49:23 1.1.1.3 +++ proxy_cache.c 1999/12/16 07:49:54 @@ -485,6 +485,17 @@ } #endif =20 +#ifdef WIN32 +/* can't open a file if it's a directory + * so must stat it first + */ + if (stat(filename, &buf) =3D=3D -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "proxy gc: stat(%s)", filename); + continue; + } +#endif + /* read the file */ fd =3D open(filename, O_RDONLY | O_BINARY); if (fd =3D=3D -1) { @@ -493,6 +504,7 @@ "proxy gc: open(%s)", filename); continue; } + if (fstat(fd, &buf) =3D=3D -1) { ap_log_error(APLOG_MARK, APLOG_ERR, r->server, "proxy gc: fstat(%s)", filename); ----=_16bj5s4tk2f7osiakafolaj5hi59f3n0ot.MFSBCHJLHS Content-Type: text/plain; charset=us-ascii; name=gc_thread.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=gc_thread.patch Index: src/modules/proxy/proxy_cache.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: c:/work/repository/apache_dev/src/modules/proxy/proxy_cache.c,v retrieving revision 1.1.1.3 diff -u -r1.1.1.3 proxy_cache.c --- proxy_cache.c 1999/09/14 15:49:23 1.1.1.3 +++ proxy_cache.c 1999/12/16 07:48:08 @@ -109,6 +109,10 @@ static time_t garbage_now, garbage_expire; static mutex *garbage_mutex =3D NULL; =20 +typedef struct { + server_rec *server; + struct pool *pool; +} gc_context; =20 int ap_proxy_garbage_init(server_rec *r, pool *p) { @@ -119,18 +123,25 @@ } =20 =20 -static int sub_garbage_coll(request_rec *r, array_header *files, +static int sub_garbage_coll(gc_context *gcc, array_header *files, const char *cachedir, const char *cachesubdir); -static void help_proxy_garbage_coll(request_rec *r); static int should_proxy_garbage_coll(request_rec *r); -#if !defined(WIN32) && !defined(MPE) && !defined(OS2) +static void help_proxy_garbage_coll(gc_context *gc); +static void help_proxy_garbage_coll2(gc_context *gc); +static int inside =3D 0; +#if !defined(MPE) && !defined(OS2) static void detached_proxy_garbage_coll(request_rec *r); #endif +#if defined(WIN32) +static thread * proxy_create_thread(void (thread_fn)(void *), void = *thread_arg); +#endif =20 =20 void ap_proxy_garbage_coll(request_rec *r) { - static int inside =3D 0; +#if defined(MPE) || defined(OS2) + gc_context gcc; +#endif =20 (void) ap_acquire_mutex(garbage_mutex); if (inside =3D=3D 1) { @@ -142,17 +153,16 @@ (void) ap_release_mutex(garbage_mutex); =20 ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */ - if (should_proxy_garbage_coll(r)) -#if !defined(WIN32) && !defined(MPE) && !defined(OS2) - detached_proxy_garbage_coll(r); + if (should_proxy_garbage_coll(r)) { +#if !defined(MPE) && !defined(OS2) + detached_proxy_garbage_coll(r); #else - help_proxy_garbage_coll(r); + gcc.pool =3D r->pool; + gcc.server =3D r->server; + help_proxy_garbage_coll(&gcc); #endif + } ap_unblock_alarms(); - - (void) ap_acquire_mutex(garbage_mutex); - inside =3D 0; - (void) ap_release_mutex(garbage_mutex); } =20 =20 @@ -203,12 +213,34 @@ return 0; } =20 -#if !defined(WIN32) && !defined(MPE) && !defined(OS2) +#if defined(WIN32) static void detached_proxy_garbage_coll(request_rec *r) { + + static struct pool *gc_pool =3D 0; + gc_context *gcc =3D 0; + + if (gc_pool) { + ap_clear_pool (gc_pool); + gc_pool =3D 0; + } + + gc_pool =3D ap_make_sub_pool (NULL); + gcc =3D (gc_context *) ap_palloc (gc_pool, sizeof (gc_context)); + gcc->pool =3D gc_pool; + gcc->server =3D r->server; + + proxy_create_thread((void (*)(void *)) help_proxy_garbage_coll, = (void *) gcc); + +} + +#else if !defined(MPE) && !defined(OS2) +static void detached_proxy_garbage_coll(request_rec *r) +{ pid_t pid; int status; pid_t pgrp; + gc_context gcc; =20 #if 0 ap_log_error(APLOG_MARK, APLOG_DEBUG, r->server, @@ -256,7 +288,12 @@ exit(1); } #endif - help_proxy_garbage_coll(r); + + gcc.pool =3D r->pool; + gcc.server =3D r->server; + + help_proxy_garbage_coll(&gcc); + exit(0); =20 default: /* Father */ @@ -268,8 +305,12 @@ /* Wait until grandson has been forked off */ /* (without wait we'd leave a zombie) */ waitpid(pid, &status, 0); + + inside =3D 0; + return; } + } #endif /* ndef WIN32 */ =20 @@ -342,11 +383,22 @@ =20 return 1; } + +static void help_proxy_garbage_coll(gc_context *gcc) +{ + + help_proxy_garbage_coll2(gcc); + + (void) ap_acquire_mutex(garbage_mutex); + inside =3D 0; + (void) ap_release_mutex(garbage_mutex); + +} =20 -static void help_proxy_garbage_coll(request_rec *r) +static void help_proxy_garbage_coll2(gc_context *gcc) { const char *cachedir; - void *sconf =3D r->server->module_config; + void *sconf =3D gcc->server->module_config; proxy_server_conf *pconf =3D (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); const struct cache_conf *conf =3D &pconf->cache; @@ -356,20 +408,20 @@ int i; =20 cachedir =3D conf->root; - filename =3D ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); + filename =3D ap_palloc(gcc->pool, strlen(cachedir) + HASH_LEN + 2); /* configured size is given in kB. Make it bytes, convert to = long61_t: */ cachesize.lower =3D cachesize.upper =3D 0; add_long61(&cachesize, conf->space << 10); =20 ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */ =20 - files =3D ap_make_array(r->pool, 100, sizeof(struct gc_ent)); + files =3D ap_make_array(gcc->pool, 100, sizeof(struct gc_ent)); curbytes.upper =3D curbytes.lower =3D 0L; =20 - sub_garbage_coll(r, files, cachedir, "/"); + sub_garbage_coll(gcc, files, cachedir, "/"); =20 if (cmp_long61(&curbytes, &cachesize) < 0L) { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, gcc->server, "proxy GC: Cache is %ld%% full (nothing deleted)", = (long)(((curbytes.upper<<20)|(curbytes.lower>>10))*100/conf->space)); ap_unblock_alarms(); @@ -388,7 +440,7 @@ #else if (unlink(filename) =3D=3D -1) { if (errno !=3D ENOENT) - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + ap_log_error(APLOG_MARK, APLOG_ERR, gcc->server, "proxy gc: unlink(%s)", filename); } else @@ -400,13 +452,13 @@ } } =20 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, gcc->server, "proxy GC: Cache is %ld%% full (%d deleted)", (long)(((curbytes.upper<<20)|(curbytes.lower>>10))*100/conf->space),= i); ap_unblock_alarms(); } =20 -static int sub_garbage_coll(request_rec *r, array_header *files, +static int sub_garbage_coll(gc_context *gcc, array_header *files, const char *cachebasedir, const char *cachesubdir) { char line[27]; @@ -424,11 +476,11 @@ char *filename; =20 ap_snprintf(cachedir, sizeof(cachedir), "%s%s", cachebasedir, = cachesubdir); - filename =3D ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); + filename =3D ap_palloc(gcc->pool, strlen(cachedir) + HASH_LEN + 2); Explain1("GC Examining directory %s", cachedir); dir =3D opendir(cachedir); if (dir =3D=3D NULL) { - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + ap_log_error(APLOG_MARK, APLOG_ERR, gcc->server, "proxy gc: opendir(%s)", cachedir); return 0; } @@ -443,13 +495,13 @@ /* then stat it to see how old it is; delete temporary files > 1 day old= */ if (stat(filename, &buf) =3D=3D -1) { if (errno !=3D ENOENT) - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + ap_log_error(APLOG_MARK, APLOG_ERR, gcc->server, "proxy gc: stat(%s)", filename); } else if (garbage_now !=3D -1 && buf.st_atime < garbage_now - = SEC_ONE_DAY && buf.st_mtime < garbage_now - SEC_ONE_DAY) { Explain1("GC unlink %s", filename); - ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, r->server, + ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, gcc->server, "proxy gc: deleting orphaned cache file %s", filename); #if TESTING fprintf(stderr, "Would unlink %s\n", filename); @@ -485,16 +537,27 @@ } #endif =20 +#ifdef WIN32 +/* can't open a file if it's a directory + * so must stat it first + */ + if (stat(filename, &buf) =3D=3D -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, gcc->server, + "proxy gc: stat(%s)", filename); + continue; + } +#endif + /* read the file */ fd =3D open(filename, O_RDONLY | O_BINARY); if (fd =3D=3D -1) { if (errno !=3D ENOENT) - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + ap_log_error(APLOG_MARK, APLOG_ERR, gcc->server, "proxy gc: open(%s)", filename); continue; } if (fstat(fd, &buf) =3D=3D -1) { - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + ap_log_error(APLOG_MARK, APLOG_ERR, gcc->server, "proxy gc: fstat(%s)", filename); close(fd); continue; @@ -507,7 +570,7 @@ close(fd); ap_snprintf(newcachedir, sizeof(newcachedir), "%s%s/", cachesubdir, ent->d_name); - if (!sub_garbage_coll(r, files, cachebasedir, newcachedir)) { + if (!sub_garbage_coll(gcc, files, cachebasedir, newcachedir)) { ap_snprintf(newcachedir, sizeof(newcachedir), "%s%s", cachedir, ent->d_name); #if TESTING @@ -527,7 +590,7 @@ i =3D read(fd, line, 26); close(fd); if (i =3D=3D -1) { - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + ap_log_error(APLOG_MARK, APLOG_ERR, gcc->server, "proxy gc: read(%s)", filename); continue; } @@ -538,7 +601,7 @@ /* bad file */ if (garbage_now !=3D -1 && buf.st_atime > garbage_now + SEC_ONE_DAY= && buf.st_mtime > garbage_now + SEC_ONE_DAY) { - ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, r->server, + ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, gcc->server, "proxy: deleting bad cache file with future date: %s", = filename); #if TESTING fprintf(stderr, "Would unlink bad file %s\n", filename); @@ -581,6 +644,7 @@ { char urlbuff[1034], *strp; int len; + /* read the data from the cache file */ /* format * date SP lastmod SP expire SP count SP content-length CRLF @@ -594,7 +658,7 @@ urlbuff[len - 1] =3D '\0'; =20 if (!ap_checkmask(urlbuff, - "&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&")) + "&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&")) return 0; =20 c->date =3D ap_proxy_hex2sec(urlbuff); @@ -695,10 +759,11 @@ cachefp =3D NULL; /* find out about whether the request can access the cache */ pragma =3D ap_table_get(r->headers_in, "Pragma"); + auth =3D ap_table_get(r->headers_in, "Authorization"); Explain5("Request for %s, pragma=3D%s, auth=3D%s, ims=3D%ld, = imstr=3D%s", url, pragma, auth, c->ims, imstr); - if (c->filename !=3D NULL && r->method_number =3D=3D M_GET && + if (c->filename !=3D NULL && (r->method_number =3D=3D M_GET) && strlen(url) < 1024 && !ap_proxy_liststr(pragma, "no-cache") && auth =3D=3D NULL) { Explain1("Check file %s", c->filename); @@ -1176,3 +1241,17 @@ #endif =20 } + +#if defined(WIN32) +static thread * +proxy_create_thread(void (thread_fn)(void *), void *thread_arg) +{ + int id; + int rv; + =20 + rv =3D _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE)thread_fn, + thread_arg, 0, &id); + + return((thread *)rv); +} +#endif ----=_16bj5s4tk2f7osiakafolaj5hi59f3n0ot.MFSBCHJLHS Content-Type: text/plain; charset=us-ascii; name=tls.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=tls.patch Index: src/modules/proxy/mod_proxy.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: c:/work/repository/apache_dev/src/modules/proxy/mod_proxy.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 mod_proxy.h --- mod_proxy.h 1999/09/13 15:36:59 1.1.1.1 +++ mod_proxy.h 1999/12/10 16:53:04 @@ -217,7 +217,7 @@ via_off, via_on, via_block, - via_full + via_full=20 } viaopt; /* how to deal with proxy Via: headers = */ size_t recv_buffer_size; } proxy_server_conf; @@ -256,6 +256,11 @@ cache_req *cache; }; =20 +struct per_thread_data { + struct hostent hpbuf; + u_long ipaddr; + char *charpbuf[2]; +}; /* Function prototypes */ =20 /* proxy_cache.c */ Index: src/modules/proxy/proxy_util.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: c:/work/repository/apache_dev/src/modules/proxy/proxy_util.c,v retrieving revision 1.1.1.3 retrieving revision 1.1.1.3.2.1 diff -u -r1.1.1.3 -r1.1.1.3.2.1 --- proxy_util.c 1999/09/14 15:49:25 1.1.1.3 +++ proxy_util.c 1999/09/15 16:56:07 1.1.1.3.2.1 @@ -68,7 +68,7 @@ static int proxy_match_domainname(struct dirconn_entry *This, = request_rec *r); static int proxy_match_hostname(struct dirconn_entry *This, request_rec = *r); static int proxy_match_word(struct dirconn_entry *This, request_rec *r); - +static struct per_thread_data *get_per_thread_data(); /* already called in the knowledge that the characters are hex digits */ int ap_proxy_hex2c(const char *x) { @@ -863,9 +863,7 @@ { int i; struct hostent *hp; - static APACHE_TLS struct hostent hpbuf; - static APACHE_TLS u_long ipaddr; - static APACHE_TLS char *charpbuf[2]; + struct per_thread_data *ptd =3D get_per_thread_data(); =20 for (i =3D 0; host[i] !=3D '\0'; i++) if (!ap_isdigit(host[i]) && host[i] !=3D '.') @@ -877,17 +875,17 @@ return "Host not found"; } else { - ipaddr =3D ap_inet_addr(host); - hp =3D gethostbyaddr((char *) &ipaddr, sizeof(u_long), AF_INET); + ptd->ipaddr =3D ap_inet_addr(host); + hp =3D gethostbyaddr((char *) &ptd->ipaddr, sizeof(u_long), AF_INET); if (hp =3D=3D NULL) { - memset(&hpbuf, 0, sizeof(hpbuf)); - hpbuf.h_name =3D 0; - hpbuf.h_addrtype =3D AF_INET; - hpbuf.h_length =3D sizeof(u_long); - hpbuf.h_addr_list =3D charpbuf; - hpbuf.h_addr_list[0] =3D (char *) &ipaddr; - hpbuf.h_addr_list[1] =3D 0; - hp =3D &hpbuf; + memset(&ptd->hpbuf, 0, sizeof(ptd->hpbuf)); + ptd->hpbuf.h_name =3D 0; + ptd->hpbuf.h_addrtype =3D AF_INET; + ptd->hpbuf.h_length =3D sizeof(u_long); + ptd->hpbuf.h_addr_list =3D ptd->charpbuf; + ptd->hpbuf.h_addr_list[0] =3D (char *) &ptd->ipaddr; + ptd->hpbuf.h_addr_list[1] =3D 0; + hp =3D &ptd->hpbuf; } } *reqhp =3D *hp; @@ -1286,3 +1284,44 @@ return len; } =20 +#if defined WIN32 + +static DWORD tls_index; + +BOOL WINAPI proxy_dll_main (HINSTANCE dllhandle, DWORD reason, LPVOID = reserved) +{ + LPVOID memptr; + + switch (reason) { + case DLL_PROCESS_ATTACH: + tls_index =3D TlsAlloc(); + case DLL_THREAD_ATTACH: /* intentional no break */ + TlsSetValue (tls_index, malloc (sizeof (struct per_thread_data))); + break; + case DLL_THREAD_DETACH: + memptr =3D TlsGetValue (tls_index); + if (memptr) { + free (memptr); + TlsSetValue (tls_index, 0); + } + break; + } + + return TRUE; +} + +#endif + +static struct per_thread_data *get_per_thread_data() +{ + +#if defined WIN32 + + return (struct per_thread_data *) TlsGetValue (tls_index); + +#else + static APACHE_TLS per_thread_data sptd; + return *sptd; +#endif + +} ----=_16bj5s4tk2f7osiakafolaj5hi59f3n0ot.MFSBCHJLHS--