* cygtls.h (struct _local_storage): Add thread storage pointers for
memory used by socket select functions. Combine them into a single struct select. * cygtls.cc: Accommodate above change throughout. (_cygtls::init_thread): Drop initalizing of sockevt to INVALID_HANDLE_VALUE. (_cygtls::fixup_after_fork): Reset sockevt to NULL. (_cygtls::remove): Don't use sockevt value to bail out prematurely. Set sockevt to NULL. Free malloced select members. * select.h (struct select_socket_info): Drop max_w4 member. * select.cc (thread_socket): Use INFINITE timeout value if number of objects to wait for is <= MAXIMUM_WAIT_OBJECTS. Use num_w4 member of select_socket_info struct rather than dropped max_w4. (init_tls_select_info): New inline function to initialize TLS select members. (start_thread_socket): Just call init_tls_select_info to initialize TLS select members and use them later on. (socket_cleanup): Don't free select_socket_info pointer members since they are thread local now.
This commit is contained in:
parent
1183d7fb13
commit
023c25829c
|
@ -1,3 +1,25 @@
|
||||||
|
2009-07-06 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* cygtls.h (struct _local_storage): Add thread storage pointers for
|
||||||
|
memory used by socket select functions. Combine them into a single
|
||||||
|
struct select.
|
||||||
|
* cygtls.cc: Accommodate above change throughout.
|
||||||
|
(_cygtls::init_thread): Drop initalizing of sockevt to
|
||||||
|
INVALID_HANDLE_VALUE.
|
||||||
|
(_cygtls::fixup_after_fork): Reset sockevt to NULL.
|
||||||
|
(_cygtls::remove): Don't use sockevt value to bail out prematurely.
|
||||||
|
Set sockevt to NULL. Free malloced select members.
|
||||||
|
* select.h (struct select_socket_info): Drop max_w4 member.
|
||||||
|
* select.cc (thread_socket): Use INFINITE timeout value if number of
|
||||||
|
objects to wait for is <= MAXIMUM_WAIT_OBJECTS. Use num_w4 member
|
||||||
|
of select_socket_info struct rather than dropped max_w4.
|
||||||
|
(init_tls_select_info): New inline function to initialize TLS select
|
||||||
|
members.
|
||||||
|
(start_thread_socket): Just call init_tls_select_info to initialize TLS
|
||||||
|
select members and use them later on.
|
||||||
|
(socket_cleanup): Don't free select_socket_info pointer members since
|
||||||
|
they are thread local now.
|
||||||
|
|
||||||
2009-07-06 Christopher Faylor <me+cygwin@cgf.cx>
|
2009-07-06 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* dtable.cc (handle_to_fn): Detect failing NtQueryObject.
|
* dtable.cc (handle_to_fn): Detect failing NtQueryObject.
|
||||||
|
|
|
@ -96,7 +96,6 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
|
||||||
|
|
||||||
thread_id = GetCurrentThreadId ();
|
thread_id = GetCurrentThreadId ();
|
||||||
initialized = CYGTLS_INITIALIZED;
|
initialized = CYGTLS_INITIALIZED;
|
||||||
locals.select_sockevt = INVALID_HANDLE_VALUE;
|
|
||||||
errno_addr = &(local_clib._errno);
|
errno_addr = &(local_clib._errno);
|
||||||
|
|
||||||
if ((void *) func == (void *) cygthread::stub
|
if ((void *) func == (void *) cygthread::stub
|
||||||
|
@ -126,7 +125,7 @@ _cygtls::fixup_after_fork ()
|
||||||
sig = 0;
|
sig = 0;
|
||||||
}
|
}
|
||||||
stacklock = spinning = 0;
|
stacklock = spinning = 0;
|
||||||
locals.select_sockevt = INVALID_HANDLE_VALUE;
|
locals.select.sockevt = NULL;
|
||||||
wq.thread_ev = NULL;
|
wq.thread_ev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +140,7 @@ void
|
||||||
_cygtls::remove (DWORD wait)
|
_cygtls::remove (DWORD wait)
|
||||||
{
|
{
|
||||||
initialized = 0;
|
initialized = 0;
|
||||||
if (!locals.select_sockevt || exit_state >= ES_FINAL)
|
if (exit_state >= ES_FINAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
debug_printf ("wait %p", wait);
|
debug_printf ("wait %p", wait);
|
||||||
|
@ -149,10 +148,12 @@ _cygtls::remove (DWORD wait)
|
||||||
{
|
{
|
||||||
/* FIXME: Need some sort of atthreadexit function to allow things like
|
/* FIXME: Need some sort of atthreadexit function to allow things like
|
||||||
select to control this themselves. */
|
select to control this themselves. */
|
||||||
if (locals.select_sockevt != INVALID_HANDLE_VALUE)
|
if (!locals.select.sockevt)
|
||||||
{
|
{
|
||||||
CloseHandle (locals.select_sockevt);
|
CloseHandle (locals.select.sockevt);
|
||||||
locals.select_sockevt = (HANDLE) NULL;
|
locals.select.sockevt = NULL;
|
||||||
|
free_local (select.ser_num);
|
||||||
|
free_local (select.w4);
|
||||||
}
|
}
|
||||||
free_local (process_ident);
|
free_local (process_ident);
|
||||||
free_local (ntoa_buf);
|
free_local (ntoa_buf);
|
||||||
|
|
|
@ -104,7 +104,12 @@ struct _local_storage
|
||||||
char mnt_dir[CYG_MAX_PATH];
|
char mnt_dir[CYG_MAX_PATH];
|
||||||
|
|
||||||
/* select.cc */
|
/* select.cc */
|
||||||
HANDLE select_sockevt;
|
struct {
|
||||||
|
HANDLE sockevt;
|
||||||
|
int max_w4;
|
||||||
|
LONG *ser_num; // note: malloced
|
||||||
|
HANDLE *w4; // note: malloced
|
||||||
|
} select;
|
||||||
|
|
||||||
/* strerror */
|
/* strerror */
|
||||||
char strerror_buf[sizeof ("Unknown error 4294967295")];
|
char strerror_buf[sizeof ("Unknown error 4294967295")];
|
||||||
|
|
|
@ -16,6 +16,7 @@ details. */
|
||||||
|
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
|
||||||
#include <wingdi.h>
|
#include <wingdi.h>
|
||||||
|
@ -1315,7 +1316,10 @@ static DWORD WINAPI
|
||||||
thread_socket (void *arg)
|
thread_socket (void *arg)
|
||||||
{
|
{
|
||||||
select_socket_info *si = (select_socket_info *) arg;
|
select_socket_info *si = (select_socket_info *) arg;
|
||||||
DWORD timeout = 64 / (si->max_w4 / MAXIMUM_WAIT_OBJECTS);
|
DWORD timeout = (si->num_w4 <= MAXIMUM_WAIT_OBJECTS)
|
||||||
|
? INFINITE
|
||||||
|
: (64 / (roundup2 (si->num_w4, MAXIMUM_WAIT_OBJECTS)
|
||||||
|
/ MAXIMUM_WAIT_OBJECTS));
|
||||||
bool event = false;
|
bool event = false;
|
||||||
|
|
||||||
select_printf ("stuff_start %p", si->start);
|
select_printf ("stuff_start %p", si->start);
|
||||||
|
@ -1326,18 +1330,19 @@ thread_socket (void *arg)
|
||||||
if (peek_socket (s, false))
|
if (peek_socket (s, false))
|
||||||
event = true;
|
event = true;
|
||||||
if (!event)
|
if (!event)
|
||||||
for (int i = 0; i < si->max_w4; i += MAXIMUM_WAIT_OBJECTS)
|
for (int i = 0; i < si->num_w4; i += MAXIMUM_WAIT_OBJECTS)
|
||||||
switch (WaitForMultipleObjects (min (si->num_w4 - i,
|
switch (WaitForMultipleObjects (min (si->num_w4 - i,
|
||||||
MAXIMUM_WAIT_OBJECTS),
|
MAXIMUM_WAIT_OBJECTS),
|
||||||
si->w4 + i, FALSE, timeout))
|
si->w4 + i, FALSE, timeout))
|
||||||
{
|
{
|
||||||
case WAIT_FAILED:
|
case WAIT_FAILED:
|
||||||
goto out;
|
goto out;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
continue;
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
if (!i) /* Socket event set. */
|
if (!i) /* Socket event set. */
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
/*FALLTHRU*/
|
||||||
case WAIT_TIMEOUT:
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1347,6 +1352,36 @@ out:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool init_tls_select_info () __attribute__ ((always_inline));
|
||||||
|
static inline bool
|
||||||
|
init_tls_select_info ()
|
||||||
|
{
|
||||||
|
if (!_my_tls.locals.select.sockevt)
|
||||||
|
{
|
||||||
|
_my_tls.locals.select.sockevt = CreateEvent (&sec_none_nih, TRUE, FALSE,
|
||||||
|
NULL);
|
||||||
|
if (!_my_tls.locals.select.sockevt)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!_my_tls.locals.select.ser_num)
|
||||||
|
{
|
||||||
|
_my_tls.locals.select.ser_num
|
||||||
|
= (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
|
||||||
|
if (!_my_tls.locals.select.ser_num)
|
||||||
|
return false;
|
||||||
|
_my_tls.locals.select.w4
|
||||||
|
= (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
|
||||||
|
if (!_my_tls.locals.select.w4)
|
||||||
|
{
|
||||||
|
free (_my_tls.locals.select.ser_num);
|
||||||
|
_my_tls.locals.select.ser_num = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_my_tls.locals.select.max_w4 = MAXIMUM_WAIT_OBJECTS;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
start_thread_socket (select_record *me, select_stuff *stuff)
|
start_thread_socket (select_record *me, select_stuff *stuff)
|
||||||
{
|
{
|
||||||
|
@ -1359,19 +1394,17 @@ start_thread_socket (select_record *me, select_stuff *stuff)
|
||||||
}
|
}
|
||||||
|
|
||||||
si = new select_socket_info;
|
si = new select_socket_info;
|
||||||
si->ser_num = (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
|
|
||||||
si->w4 = (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
|
if (!init_tls_select_info ())
|
||||||
if (!si->ser_num || !si->w4)
|
|
||||||
return 0;
|
return 0;
|
||||||
si->max_w4 = MAXIMUM_WAIT_OBJECTS;
|
|
||||||
select_record *s = &stuff->start;
|
si->ser_num = _my_tls.locals.select.ser_num;
|
||||||
if (_my_tls.locals.select_sockevt != INVALID_HANDLE_VALUE)
|
si->w4 = _my_tls.locals.select.w4;
|
||||||
si->w4[0] = _my_tls.locals.select_sockevt;
|
|
||||||
else if (!(si->w4[0] = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL)))
|
si->w4[0] = _my_tls.locals.select.sockevt;
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
_my_tls.locals.select_sockevt = si->w4[0];
|
|
||||||
si->num_w4 = 1;
|
si->num_w4 = 1;
|
||||||
|
|
||||||
|
select_record *s = &stuff->start;
|
||||||
while ((s = s->next))
|
while ((s = s->next))
|
||||||
if (s->startup == start_thread_socket)
|
if (s->startup == start_thread_socket)
|
||||||
{
|
{
|
||||||
|
@ -1382,21 +1415,23 @@ start_thread_socket (select_record *me, select_stuff *stuff)
|
||||||
for (int i = 1; i < si->num_w4; ++i)
|
for (int i = 1; i < si->num_w4; ++i)
|
||||||
if (si->ser_num[i] == ser_num)
|
if (si->ser_num[i] == ser_num)
|
||||||
goto continue_outer_loop;
|
goto continue_outer_loop;
|
||||||
if (si->num_w4 >= si->max_w4)
|
if (si->num_w4 >= _my_tls.locals.select.max_w4)
|
||||||
{
|
{
|
||||||
LONG *nser = (LONG *) realloc (si->ser_num,
|
LONG *nser = (LONG *) realloc (si->ser_num,
|
||||||
(si->max_w4 + MAXIMUM_WAIT_OBJECTS)
|
(_my_tls.locals.select.max_w4
|
||||||
|
+ MAXIMUM_WAIT_OBJECTS)
|
||||||
* sizeof (LONG));
|
* sizeof (LONG));
|
||||||
if (!nser)
|
if (!nser)
|
||||||
return 0;
|
return 0;
|
||||||
si->ser_num = nser;
|
_my_tls.locals.select.ser_num = si->ser_num = nser;
|
||||||
HANDLE *nw4 = (HANDLE *) realloc (si->w4,
|
HANDLE *nw4 = (HANDLE *) realloc (si->w4,
|
||||||
(si->max_w4 + MAXIMUM_WAIT_OBJECTS)
|
(_my_tls.locals.select.max_w4
|
||||||
|
+ MAXIMUM_WAIT_OBJECTS)
|
||||||
* sizeof (HANDLE));
|
* sizeof (HANDLE));
|
||||||
if (!nw4)
|
if (!nw4)
|
||||||
return 0;
|
return 0;
|
||||||
si->w4 = nw4;
|
_my_tls.locals.select.w4 = si->w4 = nw4;
|
||||||
si->max_w4 += MAXIMUM_WAIT_OBJECTS;
|
_my_tls.locals.select.max_w4 += MAXIMUM_WAIT_OBJECTS;
|
||||||
}
|
}
|
||||||
si->ser_num[si->num_w4] = ser_num;
|
si->ser_num[si->num_w4] = ser_num;
|
||||||
si->w4[si->num_w4++] = ((fhandler_socket *) s->fh)->wsock_event ();
|
si->w4[si->num_w4++] = ((fhandler_socket *) s->fh)->wsock_event ();
|
||||||
|
@ -1423,10 +1458,6 @@ socket_cleanup (select_record *, select_stuff *stuff)
|
||||||
si->thread->detach ();
|
si->thread->detach ();
|
||||||
ResetEvent (si->w4[0]);
|
ResetEvent (si->w4[0]);
|
||||||
stuff->device_specific_socket = NULL;
|
stuff->device_specific_socket = NULL;
|
||||||
if (si->ser_num)
|
|
||||||
free (si->ser_num);
|
|
||||||
if (si->w4)
|
|
||||||
free (si->w4);
|
|
||||||
delete si;
|
delete si;
|
||||||
}
|
}
|
||||||
select_printf ("returning");
|
select_printf ("returning");
|
||||||
|
|
|
@ -58,7 +58,6 @@ struct select_pipe_info: public select_info
|
||||||
|
|
||||||
struct select_socket_info: public select_info
|
struct select_socket_info: public select_info
|
||||||
{
|
{
|
||||||
int max_w4;
|
|
||||||
int num_w4;
|
int num_w4;
|
||||||
LONG *ser_num;
|
LONG *ser_num;
|
||||||
HANDLE *w4;
|
HANDLE *w4;
|
||||||
|
|
Loading…
Reference in New Issue