* cygthread.cc (cygthread::is): Eliminate.

* cygthread.h (cygthread::is): Eliminate declaratin.
* fhandler_console.cc (fhandler_console::read): Only wait for signal_arrived in
the main thread.
* fhandler_socket.cc: Include new "wininfo.h".
(fhandler_socket::ioctl): Use 'winmsg' rather than 'gethwnd()'.
* sync.cc (muto::grab): Define new function.
(muto::acquire): Use tls pointer rather than tid.
(muto::acquired): Ditto.
(muto::reset): Delete.
(muto::release): Ditto.  Also implement "close on last release".
* sync.h (muto::tid): Delete.
(muto::tls): New field.
(muto::ismine): Delete.
(muto::owner): Delete.
(muto::unstable): Delete.
(muto::reset): Delete.
(muto::upforgrabs): New method.
(muto::grab): Ditto.
(new_muto_name): New define.
* wininfo.h: New file.
(wininfo): New class.
* window.cc: Rework throughout to use winfo class for controlling invisible
window operation.
(gethwnd): Delete definition.
* winsup.h (gethwnd): Delete declaration.
This commit is contained in:
Christopher Faylor 2004-05-16 04:18:50 +00:00
parent aafd8a545f
commit 0c565ab35b
9 changed files with 150 additions and 102 deletions

View File

@ -1,3 +1,32 @@
2004-05-15 Christopher Faylor <cgf@alum.bu.edu>
* cygthread.cc (cygthread::is): Eliminate.
* cygthread.h (cygthread::is): Eliminate declaratin.
* fhandler_console.cc (fhandler_console::read): Only wait for
signal_arrived in the main thread.
* fhandler_socket.cc: Include new "wininfo.h".
(fhandler_socket::ioctl): Use 'winmsg' rather than 'gethwnd()'.
* sync.cc (muto::grab): Define new function.
(muto::acquire): Use tls pointer rather than tid.
(muto::acquired): Ditto.
(muto::reset): Delete.
(muto::release): Ditto. Also implement "close on last release".
* sync.h (muto::tid): Delete.
(muto::tls): New field.
(muto::ismine): Delete.
(muto::owner): Delete.
(muto::unstable): Delete.
(muto::reset): Delete.
(muto::upforgrabs): New method.
(muto::grab): Ditto.
(new_muto_name): New define.
* wininfo.h: New file.
(wininfo): New class.
* window.cc: Rework throughout to use winfo class for controlling
invisible window operation.
(gethwnd): Delete definition.
* winsup.h (gethwnd): Delete declaration.
2004-05-15 Christopher Faylor <cgf@alum.bu.edu> 2004-05-15 Christopher Faylor <cgf@alum.bu.edu>
* cygheap.h: Remove some parameter names from declarations throughout. * cygheap.h: Remove some parameter names from declarations throughout.

View File

@ -101,18 +101,6 @@ cygthread::init ()
main_thread_id = GetCurrentThreadId (); main_thread_id = GetCurrentThreadId ();
} }
bool
cygthread::is ()
{
DWORD tid = GetCurrentThreadId ();
for (DWORD i = 0; i < NTHREADS; i++)
if (threads[i].id == tid)
return 1;
return 0;
}
cygthread * cygthread *
cygthread::freerange () cygthread::freerange ()
{ {

View File

@ -30,7 +30,6 @@ class cygthread
static void init (); static void init ();
bool detach (HANDLE = NULL); bool detach (HANDLE = NULL);
operator HANDLE (); operator HANDLE ();
static bool is ();
void * operator new (size_t); void * operator new (size_t);
static cygthread *freerange (); static cygthread *freerange ();
void exit_thread (); void exit_thread ();

View File

@ -29,6 +29,7 @@ details. */
#include "pinfo.h" #include "pinfo.h"
#include "shared_info.h" #include "shared_info.h"
#include "cygthread.h" #include "cygthread.h"
#include "cygtls.h"
#define CONVERT_LIMIT 16384 #define CONVERT_LIMIT 16384
@ -250,7 +251,7 @@ fhandler_console::read (void *pv, size_t& buflen)
char tmp[60]; char tmp[60];
w4[0] = h; w4[0] = h;
if (cygthread::is ()) if (&_my_tls != _main_tls)
nwait = 1; nwait = 1;
else else
{ {

View File

@ -32,6 +32,7 @@
#include "sigproc.h" #include "sigproc.h"
#include "cygthread.h" #include "cygthread.h"
#include "select.h" #include "select.h"
#include "wininfo.h"
#include <unistd.h> #include <unistd.h>
extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc); extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc);
@ -1374,7 +1375,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
break; break;
} }
case FIOASYNC: case FIOASYNC:
res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
*(int *) p ? ASYNC_MASK : 0); *(int *) p ? ASYNC_MASK : 0);
syscall_printf ("Async I/O on socket %s", syscall_printf ("Async I/O on socket %s",
*(int *) p ? "started" : "cancelled"); *(int *) p ? "started" : "cancelled");
@ -1390,7 +1391,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
* blocking mode * blocking mode
*/ */
if (cmd == FIONBIO && *(int *) p == 0) if (cmd == FIONBIO && *(int *) p == 0)
WSAAsyncSelect (get_socket (), gethwnd (), 0, 0); WSAAsyncSelect (get_socket (), winmsg, 0, 0);
res = ioctlsocket (get_socket (), cmd, (unsigned long *) p); res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
if (res == SOCKET_ERROR) if (res == SOCKET_ERROR)
set_winsock_errno (); set_winsock_errno ();
@ -1400,7 +1401,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
*(int *) p ? "non" : ""); *(int *) p ? "non" : "");
/* Start AsyncSelect if async socket unblocked */ /* Start AsyncSelect if async socket unblocked */
if (*(int *) p && async_io ()) if (*(int *) p && async_io ())
WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, ASYNC_MASK); WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
set_nonblocking (*(int *) p); set_nonblocking (*(int *) p);
} }

View File

@ -22,11 +22,19 @@ details. */
#include <stdlib.h> #include <stdlib.h>
#include "sync.h" #include "sync.h"
#include "security.h" #include "security.h"
#include "thread.h"
#include "cygtls.h"
#undef WaitForSingleObject #undef WaitForSingleObject
DWORD NO_COPY muto::exiting_thread; DWORD NO_COPY muto::exiting_thread;
void
muto::grab ()
{
tls = &_my_tls;
}
/* Constructor */ /* Constructor */
muto * muto *
muto::init (const char *s) muto::init (const char *s)
@ -69,13 +77,13 @@ muto::~muto ()
int int
muto::acquire (DWORD ms) muto::acquire (DWORD ms)
{ {
DWORD this_tid = GetCurrentThreadId (); void *this_tls = &_my_tls;
#if 0 #if 0
if (exiting_thread) if (exiting_thread)
return this_tid == exiting_thread; return this_tid == exiting_thread;
#endif #endif
if (tid != this_tid) if (tls != this_tls)
{ {
/* Increment the waiters part of the class. Need to do this first to /* Increment the waiters part of the class. Need to do this first to
avoid potential races. */ avoid potential races. */
@ -97,19 +105,25 @@ muto::acquire (DWORD ms)
if (!ms) if (!ms)
InterlockedIncrement (&waiters); InterlockedIncrement (&waiters);
tid = this_tid; /* register this thread. */ tls = this_tls; /* register this thread. */
} }
return ++visits; /* Increment visit count. */ return ++visits; /* Increment visit count. */
} }
bool
muto::acquired ()
{
return tls == &_my_tls;
}
/* Return the muto lock. Needs to be called once per every acquire. */ /* Return the muto lock. Needs to be called once per every acquire. */
int int
muto::release () muto::release ()
{ {
DWORD this_tid = GetCurrentThreadId (); void *this_tls = &_my_tls;
if (tid != this_tid || !visits) if (tls != this_tls || !visits)
{ {
SetLastError (ERROR_NOT_OWNER); /* Didn't have the lock. */ SetLastError (ERROR_NOT_OWNER); /* Didn't have the lock. */
return 0; /* failed. */ return 0; /* failed. */
@ -118,33 +132,24 @@ muto::release ()
/* FIXME: Need to check that other thread has not exited, too. */ /* FIXME: Need to check that other thread has not exited, too. */
if (!--visits) if (!--visits)
{ {
tid = 0; /* We were the last unlocker. */ tls = 0; /* We were the last unlocker. */
(void) InterlockedExchange (&sync, 0); /* Reset trigger. */ (void) InterlockedExchange (&sync, 0); /* Reset trigger. */
/* This thread had incremented waiters but had never decremented it. /* This thread had incremented waiters but had never decremented it.
Decrement it now. If it is >= 0 then there are possibly other Decrement it now. If it is >= 0 then there are possibly other
threads waiting for the lock, so trigger bruteforce. */ threads waiting for the lock, so trigger bruteforce. */
if (InterlockedDecrement (&waiters) >= 0) if (InterlockedDecrement (&waiters) >= 0)
(void) SetEvent (bruteforce); /* Wake up one of the waiting threads */ (void) SetEvent (bruteforce); /* Wake up one of the waiting threads */
else if (*name == '!')
{
CloseHandle (bruteforce); /* If *name == '!' and there are no
other waiters, then this is the
last time this muto will ever be
used, so close the handle. */
#ifdef DEBUGGING
bruteforce = NULL;
#endif
}
} }
return 1; /* success. */ return 1; /* success. */
} }
bool
muto::acquired ()
{
return tid == GetCurrentThreadId ();
}
/* Call only when we're exiting. This is not thread safe. */
void
muto::reset ()
{
visits = sync = tid = 0;
InterlockedExchange (&waiters, -1);
if (bruteforce)
{
CloseHandle (bruteforce);
bruteforce = CreateEvent (&sec_none_nih, FALSE, FALSE, name);
}
}

View File

@ -22,7 +22,7 @@ class muto
HANDLE bruteforce; /* event handle used to control waiting for lock. */ HANDLE bruteforce; /* event handle used to control waiting for lock. */
public: public:
LONG visits; /* Count of number of times a thread has called acquire. */ LONG visits; /* Count of number of times a thread has called acquire. */
DWORD tid; /* Thread Id of lock owner. */ void *tls; /* Tls of lock owner. */
// class muto *next; // class muto *next;
const char *name; const char *name;
@ -35,12 +35,9 @@ public:
int acquire (DWORD ms = INFINITE) __attribute__ ((regparm (2))); /* Acquire the lock. */ int acquire (DWORD ms = INFINITE) __attribute__ ((regparm (2))); /* Acquire the lock. */
int release () __attribute__ ((regparm (1))); /* Release the lock. */ int release () __attribute__ ((regparm (1))); /* Release the lock. */
/* Return true if caller thread owns the lock. */ bool acquired () __attribute__ ((regparm (1)));
int ismine () {return tid == GetCurrentThreadId ();} void upforgrabs () {tls = this;} // just set to an invalid address
DWORD owner () {return tid;} void grab () __attribute__ ((regparm (1)));
int unstable () {return !tid && (sync || waiters >= 0);}
void reset () __attribute__ ((regparm (1)));
bool acquired ();
static void set_exiting_thread () {exiting_thread = GetCurrentThreadId ();} static void set_exiting_thread () {exiting_thread = GetCurrentThreadId ();}
}; };
@ -59,4 +56,11 @@ extern muto muto_start;
static muto __storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy1"))); \ static muto __storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy1"))); \
__name = __storage.init (#__name); \ __name = __storage.init (#__name); \
}) })
/* Use a statically allocated buffer as the storage for a muto */
#define new_muto_name(__var, __name) \
({ \
static muto __var##_storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy1"))); \
__var = __var##_storage.init (__name); \
})
#endif /*_SYNC_H*/ #endif /*_SYNC_H*/

View File

@ -24,14 +24,22 @@ details. */
#include "perprocess.h" #include "perprocess.h"
#include "security.h" #include "security.h"
#include "cygthread.h" #include "cygthread.h"
#include "thread.h"
#include "cygtls.h"
#include "sync.h"
#include "wininfo.h"
static NO_COPY UINT timer_active = 0; wininfo NO_COPY winmsg;
static NO_COPY struct itimerval itv;
static NO_COPY DWORD start_time;
static NO_COPY HWND ourhwnd = NULL;
static LRESULT CALLBACK muto NO_COPY *wininfo::lock;
WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
wininfo::wininfo ()
{
new_muto_name (lock, "!winlock");
}
int __stdcall
wininfo::process (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
#ifndef NOSTRACE #ifndef NOSTRACE
strace.wm (uMsg, wParam, lParam); strace.wm (uMsg, wParam, lParam);
@ -50,9 +58,7 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
itv.it_interval.tv_usec / 1000; itv.it_interval.tv_usec / 1000;
KillTimer (hwnd, timer_active); KillTimer (hwnd, timer_active);
if (!elapse) if (!elapse)
{ timer_active = 0;
timer_active = 0;
}
else else
{ {
timer_active = SetTimer (hwnd, 1, elapse, NULL); timer_active = SetTimer (hwnd, 1, elapse, NULL);
@ -73,19 +79,25 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} }
} }
static HANDLE window_started; static LRESULT CALLBACK
process_window_events (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return winmsg.process (hwnd, uMsg, wParam, lParam);
}
static DWORD WINAPI /* Handle windows events. Inherits ownership of the wininfo lock */
Winmain (VOID *) DWORD WINAPI
wininfo::winthread ()
{ {
MSG msg; MSG msg;
WNDCLASS wc; WNDCLASS wc;
static NO_COPY char classname[] = "CygwinWndClass"; static NO_COPY char classname[] = "CygwinWndClass";
lock->grab ();
/* Register the window class for the main window. */ /* Register the window class for the main window. */
wc.style = 0; wc.style = 0;
wc.lpfnWndProc = (WNDPROC) WndProc; wc.lpfnWndProc = (WNDPROC) process_window_events;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
wc.cbWndExtra = 0; wc.cbWndExtra = 0;
wc.hInstance = user_data->hmodule; wc.hInstance = user_data->hmodule;
@ -96,60 +108,63 @@ Winmain (VOID *)
wc.lpszClassName = classname; wc.lpszClassName = classname;
if (!RegisterClass (&wc)) if (!RegisterClass (&wc))
{ api_fatal ("cannot register window class, %E");
system_printf ("Cannot register window class, %E");
return FALSE;
}
/* Create hidden window. */ /* Create hidden window. */
ourhwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT, hwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
(HWND) NULL, (HMENU) NULL, user_data->hmodule, (HWND) NULL, (HMENU) NULL, user_data->hmodule,
(LPVOID) NULL); (LPVOID) NULL);
if (!hwnd)
api_fatal ("couldn't create window, %E");
lock->release ();
SetEvent (window_started); while (GetMessage (&msg, hwnd, 0, 0) == TRUE)
if (!ourhwnd)
{
system_printf ("Cannot create window");
return FALSE;
}
/* Start the message loop. */
while (GetMessage (&msg, ourhwnd, 0, 0) == TRUE)
DispatchMessage (&msg); DispatchMessage (&msg);
return 0; return 0;
} }
HWND __stdcall static DWORD WINAPI
gethwnd () winthread (VOID *arg)
{ {
if (ourhwnd != NULL) return ((wininfo *) arg)->winthread ();
return ourhwnd; }
cygthread *h; wininfo::operator
HWND ()
{
if (hwnd)
return hwnd;
window_started = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); lock->acquire ();
h = new cygthread (Winmain, NULL, "win"); if (!hwnd)
h->SetThreadPriority (THREAD_PRIORITY_HIGHEST); {
WaitForSingleObject (window_started, INFINITE); lock->upforgrabs ();
CloseHandle (window_started); cygthread *h = new cygthread (::winthread, this, "win");
h->zap_h (); h->SetThreadPriority (THREAD_PRIORITY_HIGHEST);
return ourhwnd; h->zap_h ();
lock->acquire ();
}
lock->release ();
return hwnd;
} }
extern "C" int extern "C" int
setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
{ {
UINT elapse;
if (which != ITIMER_REAL) if (which != ITIMER_REAL)
{ {
set_errno (ENOSYS); set_errno (ENOSYS);
return -1; return -1;
} }
return winmsg.setitimer (value, oldvalue);
}
/* FIXME: Very racy */
int __stdcall
wininfo::setitimer (const struct itimerval *value, struct itimerval *oldvalue)
{
/* Check if we will wrap */ /* Check if we will wrap */
if (itv.it_value.tv_sec >= (long) (UINT_MAX / 1000)) if (itv.it_value.tv_sec >= (long) (UINT_MAX / 1000))
{ {
@ -158,7 +173,7 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
} }
if (timer_active) if (timer_active)
{ {
KillTimer (gethwnd (), timer_active); KillTimer (winmsg, timer_active);
timer_active = 0; timer_active = 0;
} }
if (oldvalue) if (oldvalue)
@ -169,13 +184,13 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
return -1; return -1;
} }
itv = *value; itv = *value;
elapse = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; UINT elapse = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000;
if (elapse == 0) if (elapse == 0)
if (itv.it_value.tv_usec) if (itv.it_value.tv_usec)
elapse = 1; elapse = 1;
else else
return 0; return 0;
if (!(timer_active = SetTimer (gethwnd (), 1, elapse, NULL))) if (!(timer_active = SetTimer (winmsg, 1, elapse, NULL)))
{ {
__seterrno (); __seterrno ();
return -1; return -1;
@ -187,8 +202,6 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
extern "C" int extern "C" int
getitimer (int which, struct itimerval *value) getitimer (int which, struct itimerval *value)
{ {
UINT elapse, val;
if (which != ITIMER_REAL) if (which != ITIMER_REAL)
{ {
set_errno (EINVAL); set_errno (EINVAL);
@ -199,6 +212,13 @@ getitimer (int which, struct itimerval *value)
set_errno (EFAULT); set_errno (EFAULT);
return -1; return -1;
} }
return winmsg.getitimer (value);
}
/* FIXME: racy */
int __stdcall
wininfo::getitimer (struct itimerval *value)
{
*value = itv; *value = itv;
if (!timer_active) if (!timer_active)
{ {
@ -206,6 +226,9 @@ getitimer (int which, struct itimerval *value)
value->it_value.tv_usec = 0; value->it_value.tv_usec = 0;
return 0; return 0;
} }
UINT elapse, val;
elapse = GetTickCount () - start_time; elapse = GetTickCount () - start_time;
val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000;
val -= elapse; val -= elapse;

View File

@ -217,8 +217,6 @@ void events_terminate (void);
void __stdcall close_all_files (); void __stdcall close_all_files ();
/* Invisible window initialization/termination. */
HWND __stdcall gethwnd (void);
/* Check if running in a visible window station. */ /* Check if running in a visible window station. */
extern bool has_visible_window_station (void); extern bool has_visible_window_station (void);