* 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:
parent
aafd8a545f
commit
0c565ab35b
@ -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.
|
||||||
|
@ -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 ()
|
||||||
{
|
{
|
||||||
|
@ -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 ();
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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*/
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user