Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-05-16 08:18:50 +0400
committerChristopher Faylor <me@cgf.cx>2004-05-16 08:18:50 +0400
commit0c565ab35b47c29c0d5ba7a6e28ca63535776ce8 (patch)
tree3c5c40d2bb4eb150ee58f043bbec30d1032c2a74 /winsup/cygwin
parentaafd8a545f7d9089d47ac28d890840f22dac6df4 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog29
-rw-r--r--winsup/cygwin/cygthread.cc12
-rw-r--r--winsup/cygwin/cygthread.h1
-rw-r--r--winsup/cygwin/fhandler_console.cc3
-rw-r--r--winsup/cygwin/fhandler_socket.cc7
-rw-r--r--winsup/cygwin/sync.cc55
-rw-r--r--winsup/cygwin/sync.h18
-rw-r--r--winsup/cygwin/window.cc131
-rw-r--r--winsup/cygwin/winsup.h2
9 files changed, 153 insertions, 105 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f0a607908..2be855855 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,34 @@
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>
+
* cygheap.h: Remove some parameter names from declarations throughout.
(cygheap::set): Reflect changes in declaration for arguments and return
value from previous checkin.
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index d655640e0..7ad860b45 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -101,18 +101,6 @@ cygthread::init ()
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::freerange ()
{
diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h
index 9d10bb266..ff174c98c 100644
--- a/winsup/cygwin/cygthread.h
+++ b/winsup/cygwin/cygthread.h
@@ -30,7 +30,6 @@ class cygthread
static void init ();
bool detach (HANDLE = NULL);
operator HANDLE ();
- static bool is ();
void * operator new (size_t);
static cygthread *freerange ();
void exit_thread ();
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 640db218e..616090dfd 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -29,6 +29,7 @@ details. */
#include "pinfo.h"
#include "shared_info.h"
#include "cygthread.h"
+#include "cygtls.h"
#define CONVERT_LIMIT 16384
@@ -250,7 +251,7 @@ fhandler_console::read (void *pv, size_t& buflen)
char tmp[60];
w4[0] = h;
- if (cygthread::is ())
+ if (&_my_tls != _main_tls)
nwait = 1;
else
{
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index aee32ac1b..56b068cc5 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -32,6 +32,7 @@
#include "sigproc.h"
#include "cygthread.h"
#include "select.h"
+#include "wininfo.h"
#include <unistd.h>
extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc);
@@ -1374,7 +1375,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
break;
}
case FIOASYNC:
- res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO,
+ res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
*(int *) p ? ASYNC_MASK : 0);
syscall_printf ("Async I/O on socket %s",
*(int *) p ? "started" : "cancelled");
@@ -1390,7 +1391,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
* blocking mode
*/
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);
if (res == SOCKET_ERROR)
set_winsock_errno ();
@@ -1400,7 +1401,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
*(int *) p ? "non" : "");
/* Start AsyncSelect if async socket unblocked */
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);
}
diff --git a/winsup/cygwin/sync.cc b/winsup/cygwin/sync.cc
index bd89793fd..a7994048d 100644
--- a/winsup/cygwin/sync.cc
+++ b/winsup/cygwin/sync.cc
@@ -22,11 +22,19 @@ details. */
#include <stdlib.h>
#include "sync.h"
#include "security.h"
+#include "thread.h"
+#include "cygtls.h"
#undef WaitForSingleObject
DWORD NO_COPY muto::exiting_thread;
+void
+muto::grab ()
+{
+ tls = &_my_tls;
+}
+
/* Constructor */
muto *
muto::init (const char *s)
@@ -69,13 +77,13 @@ muto::~muto ()
int
muto::acquire (DWORD ms)
{
- DWORD this_tid = GetCurrentThreadId ();
+ void *this_tls = &_my_tls;
#if 0
if (exiting_thread)
return this_tid == exiting_thread;
#endif
- if (tid != this_tid)
+ if (tls != this_tls)
{
/* Increment the waiters part of the class. Need to do this first to
avoid potential races. */
@@ -97,19 +105,25 @@ muto::acquire (DWORD ms)
if (!ms)
InterlockedIncrement (&waiters);
- tid = this_tid; /* register this thread. */
+ tls = this_tls; /* register this thread. */
}
return ++visits; /* Increment visit count. */
}
+bool
+muto::acquired ()
+{
+ return tls == &_my_tls;
+}
+
/* Return the muto lock. Needs to be called once per every acquire. */
int
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. */
return 0; /* failed. */
@@ -118,33 +132,24 @@ muto::release ()
/* FIXME: Need to check that other thread has not exited, too. */
if (!--visits)
{
- tid = 0; /* We were the last unlocker. */
+ tls = 0; /* We were the last unlocker. */
(void) InterlockedExchange (&sync, 0); /* Reset trigger. */
/* This thread had incremented waiters but had never decremented it.
Decrement it now. If it is >= 0 then there are possibly other
threads waiting for the lock, so trigger bruteforce. */
if (InterlockedDecrement (&waiters) >= 0)
(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. */
}
-
-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);
- }
-}
diff --git a/winsup/cygwin/sync.h b/winsup/cygwin/sync.h
index 24de97428..7e8b60c10 100644
--- a/winsup/cygwin/sync.h
+++ b/winsup/cygwin/sync.h
@@ -22,7 +22,7 @@ class muto
HANDLE bruteforce; /* event handle used to control waiting for lock. */
public:
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;
const char *name;
@@ -35,12 +35,9 @@ public:
int acquire (DWORD ms = INFINITE) __attribute__ ((regparm (2))); /* Acquire the lock. */
int release () __attribute__ ((regparm (1))); /* Release the lock. */
- /* Return true if caller thread owns the lock. */
- int ismine () {return tid == GetCurrentThreadId ();}
- DWORD owner () {return tid;}
- int unstable () {return !tid && (sync || waiters >= 0);}
- void reset () __attribute__ ((regparm (1)));
- bool acquired ();
+ bool acquired () __attribute__ ((regparm (1)));
+ void upforgrabs () {tls = this;} // just set to an invalid address
+ void grab () __attribute__ ((regparm (1)));
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"))); \
__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*/
diff --git a/winsup/cygwin/window.cc b/winsup/cygwin/window.cc
index d005ae69b..a04f7c51d 100644
--- a/winsup/cygwin/window.cc
+++ b/winsup/cygwin/window.cc
@@ -24,14 +24,22 @@ details. */
#include "perprocess.h"
#include "security.h"
#include "cygthread.h"
+#include "thread.h"
+#include "cygtls.h"
+#include "sync.h"
+#include "wininfo.h"
-static NO_COPY UINT timer_active = 0;
-static NO_COPY struct itimerval itv;
-static NO_COPY DWORD start_time;
-static NO_COPY HWND ourhwnd = NULL;
+wininfo NO_COPY winmsg;
-static LRESULT CALLBACK
-WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+muto NO_COPY *wininfo::lock;
+
+wininfo::wininfo ()
+{
+ new_muto_name (lock, "!winlock");
+}
+
+int __stdcall
+wininfo::process (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
#ifndef NOSTRACE
strace.wm (uMsg, wParam, lParam);
@@ -50,9 +58,7 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
itv.it_interval.tv_usec / 1000;
KillTimer (hwnd, timer_active);
if (!elapse)
- {
- timer_active = 0;
- }
+ timer_active = 0;
else
{
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
-Winmain (VOID *)
+/* Handle windows events. Inherits ownership of the wininfo lock */
+DWORD WINAPI
+wininfo::winthread ()
{
MSG msg;
WNDCLASS wc;
static NO_COPY char classname[] = "CygwinWndClass";
+ lock->grab ();
/* Register the window class for the main window. */
wc.style = 0;
- wc.lpfnWndProc = (WNDPROC) WndProc;
+ wc.lpfnWndProc = (WNDPROC) process_window_events;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = user_data->hmodule;
@@ -96,60 +108,63 @@ Winmain (VOID *)
wc.lpszClassName = classname;
if (!RegisterClass (&wc))
- {
- system_printf ("Cannot register window class, %E");
- return FALSE;
- }
+ api_fatal ("cannot register window class, %E");
/* Create hidden window. */
- ourhwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- (HWND) NULL, (HMENU) NULL, user_data->hmodule,
- (LPVOID) NULL);
-
- SetEvent (window_started);
-
- if (!ourhwnd)
- {
- system_printf ("Cannot create window");
- return FALSE;
- }
-
- /* Start the message loop. */
-
- while (GetMessage (&msg, ourhwnd, 0, 0) == TRUE)
+ hwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ (HWND) NULL, (HMENU) NULL, user_data->hmodule,
+ (LPVOID) NULL);
+ if (!hwnd)
+ api_fatal ("couldn't create window, %E");
+ lock->release ();
+
+ while (GetMessage (&msg, hwnd, 0, 0) == TRUE)
DispatchMessage (&msg);
return 0;
}
-HWND __stdcall
-gethwnd ()
+static DWORD WINAPI
+winthread (VOID *arg)
{
- if (ourhwnd != NULL)
- return ourhwnd;
-
- cygthread *h;
-
- window_started = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
- h = new cygthread (Winmain, NULL, "win");
- h->SetThreadPriority (THREAD_PRIORITY_HIGHEST);
- WaitForSingleObject (window_started, INFINITE);
- CloseHandle (window_started);
- h->zap_h ();
- return ourhwnd;
+ return ((wininfo *) arg)->winthread ();
+}
+
+wininfo::operator
+HWND ()
+{
+ if (hwnd)
+ return hwnd;
+
+ lock->acquire ();
+ if (!hwnd)
+ {
+ lock->upforgrabs ();
+ cygthread *h = new cygthread (::winthread, this, "win");
+ h->SetThreadPriority (THREAD_PRIORITY_HIGHEST);
+ h->zap_h ();
+ lock->acquire ();
+ }
+ lock->release ();
+ return hwnd;
}
extern "C" int
setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
{
- UINT elapse;
-
if (which != ITIMER_REAL)
{
set_errno (ENOSYS);
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 */
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)
{
- KillTimer (gethwnd (), timer_active);
+ KillTimer (winmsg, timer_active);
timer_active = 0;
}
if (oldvalue)
@@ -169,13 +184,13 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
return -1;
}
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 (itv.it_value.tv_usec)
elapse = 1;
else
return 0;
- if (!(timer_active = SetTimer (gethwnd (), 1, elapse, NULL)))
+ if (!(timer_active = SetTimer (winmsg, 1, elapse, NULL)))
{
__seterrno ();
return -1;
@@ -187,8 +202,6 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue)
extern "C" int
getitimer (int which, struct itimerval *value)
{
- UINT elapse, val;
-
if (which != ITIMER_REAL)
{
set_errno (EINVAL);
@@ -199,6 +212,13 @@ getitimer (int which, struct itimerval *value)
set_errno (EFAULT);
return -1;
}
+ return winmsg.getitimer (value);
+}
+
+/* FIXME: racy */
+int __stdcall
+wininfo::getitimer (struct itimerval *value)
+{
*value = itv;
if (!timer_active)
{
@@ -206,6 +226,9 @@ getitimer (int which, struct itimerval *value)
value->it_value.tv_usec = 0;
return 0;
}
+
+ UINT elapse, val;
+
elapse = GetTickCount () - start_time;
val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000;
val -= elapse;
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 4c57c3776..cd698ba56 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -217,8 +217,6 @@ void events_terminate (void);
void __stdcall close_all_files ();
-/* Invisible window initialization/termination. */
-HWND __stdcall gethwnd (void);
/* Check if running in a visible window station. */
extern bool has_visible_window_station (void);