1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@981 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2000-09-27 09:11:13 +00:00
parent 25aa3816b1
commit 6f36fedaa4
5 changed files with 153 additions and 7 deletions

View file

@ -14,8 +14,13 @@
#define SIG_H
EXTERN int rb_trap_immediate;
#ifdef NT
#define TRAP_BEG (rb_trap_immediate=1, SetEvent(rb_InterruptEvent))
#define TRAP_END (rb_trap_immediate=0, ResetEvent(rb_InterruptEvent))
#else
#define TRAP_BEG (rb_trap_immediate=1)
#define TRAP_END (rb_trap_immediate=0)
#endif
EXTERN int rb_prohibit_interrupt;
#define DEFER_INTS {rb_prohibit_interrupt++;}

View file

@ -46,8 +46,8 @@ def philosopher(n)
end
end
for i in 0..N-1
Thread.start{philosopher(i)}
for n in 0..N-1
Thread.start(n){|i| philosopher(i)}
sleep 0.1
end

View file

@ -341,6 +341,14 @@ static RETSIGTYPE
sighandle(sig)
int sig;
{
#ifdef NT
#define end_interrupt() win32_thread_resume_main()
if (win32_main_context(sig, sighandle)) return;
#else
#define end_interrupt() (void)0
#endif
if (sig >= NSIG) {
rb_bug("trap_handler: Bad signal %d", sig);
}
@ -358,6 +366,7 @@ sighandle(sig)
rb_trap_pending++;
trap_pending_list[sig]++;
}
end_interrupt();
}
#ifdef SIGBUS

View file

@ -75,6 +75,22 @@ IsWinNT(void) {
return (IdOS() == VER_PLATFORM_WIN32_NT);
}
/* main thread constants */
HANDLE rb_CurrentProcessHandle;
HANDLE rb_MainThreadHandle;
DWORD rb_MainThreadId;
HANDLE rb_InterruptEvent;
HANDLE GetCurrentThreadHandle(void)
{
HANDLE h;
HANDLE proc = rb_CurrentProcessHandle;
if (!DuplicateHandle(proc, GetCurrentThread(), proc, &h,
0, FALSE, DUPLICATE_SAME_ACCESS))
return NULL;
return h;
}
/* simulate flock by locking a range on the file */
@ -160,7 +176,8 @@ flock(int fd, int oper)
// Initialization stuff
//
void
NtInitialize(int *argc, char ***argv) {
NtInitialize(int *argc, char ***argv)
{
WORD version;
int ret;
@ -1215,7 +1232,7 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
//
DIR *
opendir(const char *filename)
opendir(char *filename)
{
DIR *p;
long len;
@ -1887,6 +1904,7 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
long r;
fd_set file_rd;
fd_set file_wr;
fd_set trap;
int file_nfds;
int trap_immediate = rb_trap_immediate;
@ -1907,9 +1925,16 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
if (wr) *wr = file_wr;
return file_nfds;
}
if (ex)
trap = *ex;
else
trap.fd_count = 0;
if (trap.fd_count < FD_SETSIZE)
trap.fd_array[trap.fd_count++] = rb_InterruptEvent;
// else unable to catch interrupt.
if (trap_immediate)
TRAP_END;
if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
if ((r = select (nfds, rd, wr, &trap, timeout)) == SOCKET_ERROR) {
errno = WSAGetLastError();
switch (errno) {
case WSAEINTR:
@ -1923,7 +1948,8 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
}
static void
StartSockets () {
StartSockets ()
{
WORD version;
WSADATA retdata;
int ret;
@ -1950,6 +1976,11 @@ StartSockets () {
*/
setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
(char *)&iSockOpt, sizeof(iSockOpt));
rb_CurrentProcessHandle = GetCurrentProcess();
rb_MainThreadHandle = GetCurrentThreadHandle();
rb_MainThreadId = GetCurrentThreadId();
rb_InterruptEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
}
#undef accept
@ -2513,3 +2544,90 @@ mytimes(struct tms *tmbuf)
}
return 0;
}
static int win32_thread_exclusive(void)
{
if (GetCurrentThreadId() == rb_MainThreadId) return FALSE;
SuspendThread(rb_MainThreadHandle);
return TRUE;
}
void win32_thread_resume_main(void)
{
if (GetCurrentThreadId() != rb_MainThreadId)
ResumeThread(rb_MainThreadHandle);
}
static void win32_suspend_self(void)
{
SuspendThread(GetCurrentThread());
}
static void win32_call_handler(int arg, void (*handler)(int), CONTEXT ctx)
{
handler(arg);
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
SetThreadContext(rb_MainThreadHandle, &ctx);
}
static int catch_interrupt(unsigned long msec)
{
return !WaitForSingleObject(rb_InterruptEvent, msec);
}
int win32_interruptible(void)
{
if (catch_interrupt(0)) return TRUE;
SetEvent(rb_InterruptEvent);
return FALSE;
}
int win32_main_context(int arg, void (*handler)(int))
{
if (!win32_thread_exclusive()) return FALSE;
if (!catch_interrupt(0)) {
SetEvent(rb_InterruptEvent);
return FALSE;
}
{
CONTEXT ctx;
ZeroMemory(&ctx, sizeof(CONTEXT));
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
GetThreadContext(rb_MainThreadHandle, &ctx);
#ifdef _M_IX86
{
DWORD *esp = (DWORD *)(ctx.Esp - sizeof(CONTEXT));
*(CONTEXT *)esp = ctx;
*--esp = (DWORD)handler;
*--esp = arg;
*--esp = ctx.Eip;
ctx.Esp = (DWORD)esp;
}
ctx.Eip = (DWORD)win32_call_handler;
#else
#error
#endif
ctx.ContextFlags = CONTEXT_CONTROL;
SetThreadContext(rb_MainThreadHandle, &ctx);
}
ResumeThread(rb_MainThreadHandle);
return TRUE;
}
void win32_sleep(unsigned long msec)
{
int trap_immediate = rb_trap_immediate;
if (trap_immediate)
TRAP_END;
catch_interrupt(msec);
if (trap_immediate)
TRAP_BEG;
}

View file

@ -143,7 +143,7 @@ extern "C++" {
#define execvp _execvp
#define execvpe _execvpe
#define getpid _getpid
#define sleep(x) Sleep((x)*1000)
#define sleep(x) win32_sleep((x)*1000)
#define spawnl _spawnl
#define spawnle _spawnle
#define spawnlp _spawnlp
@ -426,4 +426,18 @@ struct tms {
#endif
#define times mytimes
/* thread stuff */
/* initialized by NtInitialize() */
HANDLE rb_CurrentProcessHandle;
HANDLE rb_MainThreadHandle;
HANDLE rb_InterruptEvent;
DWORD rb_MainThreadId;
HANDLE GetCurrentThreadHandle(void);
int win32_main_context(int arg, void (*handler)(int));
int win32_interruptible(void);
void win32_thread_resume_main(void);
void win32_sleep(unsigned long msec);
#define Sleep(msec) win32_sleep(msec)
#endif