[ruby-dev:12254] Re: lazy mswin32/mingw32(Re: データベース )
From:
nobu.nakada@...
Date:
2001-02-17 01:19:08 UTC
List:
ruby-dev #12254
なかだです。
At Wed, 14 Feb 2001 13:07:48 +0900,
matz@zetabits.com (Yukihiro Matsumoto) wrote:
> |実は僕は1.7に入れちゃっていいかな、と考えてました。
>
> 私もいいんじゃないかなって思ってます。責任はとれませんけど。
じゃそうしてもらえますか。だいたい四月以降 Windows を使えるか
どうかも不明なので、このまま握ってるのはまずそうな。
一応気づいた限りの部分は対処してみました。win32_getc()/putc()
は性能面との妥協です。うーん、あとあるとすれば read()/write()?
Index: rubysig.h
===================================================================
RCS file: /home/cvs/ruby/src/ruby/rubysig.h,v
retrieving revision 1.7
diff -u -2 -p -r1.7 rubysig.h
--- rubysig.h 2001/02/14 05:51:58 1.7
+++ rubysig.h 2001/02/16 09:46:37
@@ -23,10 +23,12 @@ typedef LONG rb_atomic_t;
/* Windows doesn't allow interrupt while system calls */
-# define TRAP_BEG win32_enter_syscall()
-# define TRAP_END win32_leave_syscall()
+# define TRAP_BEG do {\
+ rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 1);
+# define TRAP_END ATOMIC_SET(rb_trap_immediate, trap_immediate);\
+} while (0)
# define RUBY_CRITICAL(statements) do {\
- win32_disable_interrupt();\
+ win32_enter_critical();\
statements;\
- win32_enable_interrupt();\
+ win32_leave_critical();\
} while (0)
#else
Index: win32/win32.c
===================================================================
RCS file: /home/cvs/ruby/src/ruby/win32/win32.c,v
retrieving revision 1.34
diff -u -2 -p -r1.34 win32.c
--- win32/win32.c 2001/02/09 15:02:14 1.34
+++ win32/win32.c 2001/02/16 09:39:29
@@ -36,13 +36,15 @@
#endif
-#if USE_INTERRUPT_WINSOCK
+#ifdef _M_IX86
+# define WIN95 1
+#else
+# undef WIN95
+#endif
-# if defined(_MSC_VER) && _MSC_VER <= 1000
-/* VC++4.0 doesn't have this. */
-extern DWORD WSAWaitForMultipleEvents(DWORD nevent, const HANDLE *events,
- BOOL waitall, DWORD timeout,
- BOOL alertable);
-# endif
+#if HAVE_WSAWAITFORMULTIPLEEVENTS
+# define USE_INTERRUPT_WINSOCK
+#endif
+#if USE_INTERRUPT_WINSOCK
# define WaitForMultipleEvents WSAWaitForMultipleEvents
# define CreateSignal() (HANDLE)WSACreateEvent()
@@ -78,4 +80,5 @@ static DWORD wait_events(HANDLE event, D
char *NTLoginName;
+#ifdef WIN95
DWORD Win32System = (DWORD)-1;
@@ -103,4 +106,8 @@ IsWinNT(void) {
return (IdOS() == VER_PLATFORM_WIN32_NT);
}
+#else
+# define IsWinNT() TRUE
+# define IsWin95() FALSE
+#endif
/* main thread constants */
@@ -178,4 +185,5 @@ flock_winnt(VALUE self, int argc, VALUE*
}
+#ifdef WIN95
static VALUE
flock_win95(VALUE self, int argc, VALUE* argv)
@@ -208,4 +216,5 @@ flock_win95(VALUE self, int argc, VALUE*
return i;
}
+#endif
#undef LK_ERR
@@ -215,4 +224,5 @@ int
flock(int fd, int oper)
{
+#ifdef WIN95
static asynchronous_func_t locker = NULL;
@@ -223,4 +233,7 @@ flock(int fd, int oper)
locker = flock_win95;
}
+#else
+ const asynchronous_func_t locker = flock_winnt;
+#endif
return win32_asynchronize(locker,
@@ -1672,4 +1685,11 @@ EXTERN_C void __cdecl _unlock(int);
#define MSVCRT_THREADS
#endif
+#ifdef MSVCRT_THREADS
+# define MTHREAD_ONLY(x) x
+# define STHREAD_ONLY(x)
+#else
+# define MTHREAD_ONLY(x)
+# define STHREAD_ONLY(x) x
+#endif
typedef struct {
@@ -1706,18 +1726,4 @@ EXTERN_C _CRTIMP ioinfo * __pioinfo[];
static int
-_alloc_osfhnd(void)
-{
- HANDLE hF = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
- int fh = _open_osfhandle((long)hF, 0);
- CloseHandle(hF);
- if (fh == -1)
- return fh;
-#ifdef MSVCRT_THREADS
- EnterCriticalSection(&(_pioinfo(fh)->lock));
-#endif
- return fh;
-}
-
-static int
my_open_osfhandle(long osfhandle, int flags)
{
@@ -1737,20 +1743,25 @@ my_open_osfhandle(long osfhandle, int fl
fileflags |= FNOINHERIT;
- /* attempt to allocate a C Runtime file handle */
- if ((fh = _alloc_osfhnd()) == -1) {
- errno = EMFILE; /* too many open files */
- _doserrno = 0L; /* not an OS error */
- return -1; /* return error to caller */
- }
+ RUBY_CRITICAL({
+ /* attempt to allocate a C Runtime file handle */
+ HANDLE hF = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
+ fh = _open_osfhandle((long)hF, 0);
+ CloseHandle(hF);
+ if (fh == -1) {
+ errno = EMFILE; /* too many open files */
+ _doserrno = 0L; /* not an OS error */
+ }
+ else {
- /* the file is open. now, set the info in _osfhnd array */
- _set_osfhnd(fh, osfhandle);
+ MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fh)->lock)));
+ /* the file is open. now, set the info in _osfhnd array */
+ _set_osfhnd(fh, osfhandle);
- fileflags |= FOPEN; /* mark as open */
+ fileflags |= FOPEN; /* mark as open */
- _osfile(fh) = fileflags; /* set osfile entry */
-#ifdef MSVCRT_THREADS
- LeaveCriticalSection(&_pioinfo(fh)->lock);
-#endif
+ _osfile(fh) = fileflags; /* set osfile entry */
+ MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fh)->lock));
+ }
+ });
return fh; /* return handle */
@@ -1798,8 +1809,8 @@ void
myfdclose(FILE *fp)
{
-#if !defined MSVCRT_THREADS
- _free_osfhnd(fileno(fp));
-#endif
- fclose(fp);
+ RUBY_CRITICAL({
+ STHREAD_ONLY(_free_osfhnd(fileno(fp)));
+ fclose(fp);
+ });
}
@@ -2036,5 +2047,6 @@ myselect (int nfds, fd_set *rd, fd_set *
#endif /* USE_INTERRUPT_WINSOCK */
- if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
+ RUBY_CRITICAL(r = select (nfds, rd, wr, ex, timeout));
+ if (r == SOCKET_ERROR) {
errno = WSAGetLastError();
switch (errno) {
@@ -2083,4 +2095,7 @@ StartSockets ()
if (!interrupted_event)
rb_fatal("Unable to create interrupt event!\n");
+ interrupted_event = CreateSignal();
+ if (!interrupted_event)
+ rb_fatal("Unable to create interrupt event!\n");
}
@@ -2095,5 +2110,6 @@ myaccept (SOCKET s, struct sockaddr *add
StartSockets();
}
- if ((r = accept (TO_SOCKET(s), addr, addrlen)) == INVALID_SOCKET)
+ RUBY_CRITICAL(r = accept (TO_SOCKET(s), addr, addrlen));
+ if (r == INVALID_SOCKET)
errno = WSAGetLastError();
return my_open_osfhandle(r, O_RDWR|O_BINARY);
@@ -2110,5 +2126,6 @@ mybind (SOCKET s, struct sockaddr *addr,
StartSockets();
}
- if ((r = bind (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = bind (TO_SOCKET(s), addr, addrlen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2124,5 +2141,6 @@ myconnect (SOCKET s, struct sockaddr *ad
StartSockets();
}
- if ((r = connect (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = connect (TO_SOCKET(s), addr, addrlen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2139,5 +2157,6 @@ mygetpeername (SOCKET s, struct sockaddr
StartSockets();
}
- if ((r = getpeername (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = getpeername (TO_SOCKET(s), addr, addrlen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2153,5 +2172,6 @@ mygetsockname (SOCKET s, struct sockaddr
StartSockets();
}
- if ((r = getsockname (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = getsockname (TO_SOCKET(s), addr, addrlen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2165,5 +2185,6 @@ mygetsockopt (SOCKET s, int level, int o
StartSockets();
}
- if ((r = getsockopt (TO_SOCKET(s), level, optname, optval, optlen)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = getsockopt (TO_SOCKET(s), level, optname, optval, optlen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2179,5 +2200,6 @@ myioctlsocket (SOCKET s, long cmd, u_lon
StartSockets();
}
- if ((r = ioctlsocket (TO_SOCKET(s), cmd, argp)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = ioctlsocket (TO_SOCKET(s), cmd, argp));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2193,5 +2215,6 @@ mylisten (SOCKET s, int backlog)
StartSockets();
}
- if ((r = listen (TO_SOCKET(s), backlog)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = listen (TO_SOCKET(s), backlog));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2207,5 +2230,6 @@ myrecv (SOCKET s, char *buf, int len, in
StartSockets();
}
- if ((r = recv (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = recv (TO_SOCKET(s), buf, len, flags));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2222,5 +2246,6 @@ myrecvfrom (SOCKET s, char *buf, int len
StartSockets();
}
- if ((r = recvfrom (TO_SOCKET(s), buf, len, flags, from, fromlen)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = recvfrom (TO_SOCKET(s), buf, len, flags, from, fromlen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2236,5 +2261,6 @@ mysend (SOCKET s, char *buf, int len, in
StartSockets();
}
- if ((r = send (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = send (TO_SOCKET(s), buf, len, flags));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2251,5 +2277,6 @@ mysendto (SOCKET s, char *buf, int len,
StartSockets();
}
- if ((r = sendto (TO_SOCKET(s), buf, len, flags, to, tolen)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = sendto (TO_SOCKET(s), buf, len, flags, to, tolen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2265,6 +2292,6 @@ mysetsockopt (SOCKET s, int level, int o
StartSockets();
}
- if ((r = setsockopt (TO_SOCKET(s), level, optname, optval, optlen))
- == SOCKET_ERROR)
+ RUBY_CRITICAL(r = setsockopt (TO_SOCKET(s), level, optname, optval, optlen));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2280,5 +2307,6 @@ myshutdown (SOCKET s, int how)
StartSockets();
}
- if ((r = shutdown (TO_SOCKET(s), how)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = shutdown (TO_SOCKET(s), how));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2294,5 +2322,6 @@ mysocket (int af, int type, int protocol
StartSockets();
}
- if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
+ RUBY_CRITICAL(s = socket (af, type, protocol));
+ if (s == INVALID_SOCKET) {
errno = WSAGetLastError();
//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
@@ -2310,5 +2339,6 @@ mygethostbyaddr (char *addr, int len, in
StartSockets();
}
- if ((r = gethostbyaddr (addr, len, type)) == NULL)
+ RUBY_CRITICAL(r = gethostbyaddr (addr, len, type));
+ if (r == NULL)
errno = WSAGetLastError();
return r;
@@ -2324,5 +2354,6 @@ mygethostbyname (char *name)
StartSockets();
}
- if ((r = gethostbyname (name)) == NULL)
+ RUBY_CRITICAL(r = gethostbyname (name));
+ if (r == NULL)
errno = WSAGetLastError();
return r;
@@ -2338,5 +2369,6 @@ mygethostname (char *name, int len)
StartSockets();
}
- if ((r = gethostname (name, len)) == SOCKET_ERROR)
+ RUBY_CRITICAL(r = gethostname (name, len));
+ if (r == SOCKET_ERROR)
errno = WSAGetLastError();
return r;
@@ -2352,5 +2384,6 @@ mygetprotobyname (char *name)
StartSockets();
}
- if ((r = getprotobyname (name)) == NULL)
+ RUBY_CRITICAL(r = getprotobyname (name));
+ if (r == NULL)
errno = WSAGetLastError();
return r;
@@ -2366,5 +2399,6 @@ mygetprotobynumber (int num)
StartSockets();
}
- if ((r = getprotobynumber (num)) == NULL)
+ RUBY_CRITICAL(r = getprotobynumber (num));
+ if (r == NULL)
errno = WSAGetLastError();
return r;
@@ -2380,5 +2414,6 @@ mygetservbyname (char *name, char *proto
StartSockets();
}
- if ((r = getservbyname (name, proto)) == NULL)
+ RUBY_CRITICAL(r = getservbyname (name, proto));
+ if (r == NULL)
errno = WSAGetLastError();
return r;
@@ -2394,5 +2429,6 @@ mygetservbyport (int port, char *proto)
StartSockets();
}
- if ((r = getservbyport (port, proto)) == NULL)
+ RUBY_CRITICAL(r = getservbyport (port, proto));
+ if (r == NULL)
errno = WSAGetLastError();
return r;
@@ -2441,12 +2477,16 @@ waitpid (pid_t pid, int *stat_loc, int o
timeout = INFINITE;
}
- if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
- pid = _cwait(stat_loc, pid, 0);
+ RUBY_CRITICAL({
+ if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
+ pid = _cwait(stat_loc, pid, 0);
+ }
+ else {
+ pid = 0;
+ }
+ });
#if !defined __BORLANDC__
- *stat_loc <<= 8;
+ if (pid) *stat_loc <<= 8;
#endif
- return pid;
- }
- return 0;
+ return pid;
}
@@ -2579,35 +2619,37 @@ myrename(const char *oldpath, const char
return -1;
}
-
- if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
- SetFileAttributesA(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
- if (!MoveFile(oldpath, newpath))
- res = -1;
-
- if (res) {
- switch (GetLastError()) {
- case ERROR_ALREADY_EXISTS:
- case ERROR_FILE_EXISTS:
- if (IsWinNT()) {
- if (MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
- res = 0;
- } else {
- for (;;) {
- if (!DeleteFile(newpath) && GetLastError() != ERROR_FILE_NOT_FOUND)
- break;
- else if (MoveFile(oldpath, newpath)) {
+ RUBY_CRITICAL({
+ if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
+ SetFileAttributesA(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
+
+ if (!MoveFile(oldpath, newpath))
+ res = -1;
+
+ if (res) {
+ switch (GetLastError()) {
+ case ERROR_ALREADY_EXISTS:
+ case ERROR_FILE_EXISTS:
+ if (IsWinNT()) {
+ if (MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
res = 0;
- break;
+ } else {
+ for (;;) {
+ if (!DeleteFile(newpath) && GetLastError() != ERROR_FILE_NOT_FOUND)
+ break;
+ else if (MoveFile(oldpath, newpath)) {
+ res = 0;
+ break;
+ }
}
}
}
}
- }
- if (res)
- errno = GetLastError();
- else
- SetFileAttributes(newpath, oldatts);
+ if (res)
+ errno = GetLastError();
+ else
+ SetFileAttributes(newpath, oldatts);
+ });
return res;
@@ -2618,4 +2660,5 @@ win32_stat(const char *path, struct stat
{
const char *p = path;
+ int ret;
if ((isdirsep(*p) && (p++, TRUE)) || /* absolute path or UNC */
@@ -2631,5 +2674,6 @@ win32_stat(const char *path, struct stat
path = s;
}
- return stat(path, st);
+ RUBY_CRITICAL(ret = stat(path, st));
+ return ret;
}
@@ -2705,5 +2749,5 @@ static LONG flag_interrupt = -1;
static volatile DWORD tlsi_interrupt = TLS_OUT_OF_INDEXES;
-void win32_disable_interrupt(void)
+void win32_enter_critical(void)
{
if (IsWinNT()) {
@@ -2726,5 +2770,5 @@ void win32_disable_interrupt(void)
}
-void win32_enable_interrupt(void)
+void win32_leave_critical(void)
{
if (IsWinNT()) {
@@ -2741,5 +2785,5 @@ struct handler_arg_t {
int arg;
int status;
- int userstate;
+ int finished;
HANDLE handshake;
};
@@ -2754,6 +2798,6 @@ static void win32_call_handler(struct ha
rb_jump_tag(status);
}
- h->userstate = 1; /* never syscall after here */
- for (;;); /* wait here in user state */
+ h->finished = 1;
+ Sleep(INFINITE); /* safe on Win95? */
}
@@ -2766,5 +2810,5 @@ static struct handler_arg_t* setup_handl
harg->arg = arg;
harg->status = 0;
- harg->userstate = 0;
+ harg->finished = 0;
harg->handshake = handshake;
return harg;
@@ -2830,5 +2874,5 @@ int win32_main_context(int arg, void (*h
RUBY_CRITICAL({
/* ensure the main thread is in user state. */
- yield_until(harg.userstate);
+ yield_until(harg.finished);
SuspendThread(main_thread.handle);
@@ -2847,5 +2891,9 @@ int win32_main_context(int arg, void (*h
int win32_sleep(unsigned long msec)
{
- return wait_events(NULL, msec) != WAIT_TIMEOUT;
+ DWORD ret;
+ RUBY_CRITICAL(ret = wait_events(NULL, msec));
+ yield_once();
+ CHECK_INTS;
+ return ret != WAIT_TIMEOUT;
}
@@ -2853,20 +2901,38 @@ static void catch_interrupt(void)
{
yield_once();
- win32_sleep(0);
+ RUBY_CRITICAL(wait_events(NULL, 0));
CHECK_INTS;
}
-void win32_enter_syscall(void)
+#undef fgetc
+int win32_getc(FILE* stream)
{
- InterlockedExchange(&rb_trap_immediate, 1);
- catch_interrupt();
- win32_disable_interrupt();
+ int c, trap_immediate = rb_trap_immediate;
+ if (--stream->_cnt >= 0) {
+ c = (unsigned char)*stream->_ptr++;
+ rb_trap_immediate = trap_immediate;
+ }
+ else {
+ c = _filbuf(stream);
+ rb_trap_immediate = trap_immediate;
+ catch_interrupt();
+ }
+ return c;
}
-void win32_leave_syscall(void)
+#undef fputc
+int win32_putc(int c, FILE* stream)
{
- win32_enable_interrupt();
- catch_interrupt();
- InterlockedExchange(&rb_trap_immediate, 0);
+ int trap_immediate = rb_trap_immediate;
+ if (--stream->_cnt >= 0) {
+ c = (unsigned char)(*stream->_ptr++ = (char)c);
+ rb_trap_immediate = trap_immediate;
+ }
+ else {
+ c = _flsbuf(c, stream);
+ rb_trap_immediate = trap_immediate;
+ catch_interrupt();
+ }
+ return c;
}
Index: win32/win32.h
===================================================================
RCS file: /home/cvs/ruby/src/ruby/win32/win32.h,v
retrieving revision 1.15
diff -u -2 -p -r1.15 win32.h
--- win32/win32.h 2001/02/09 15:02:14 1.15
+++ win32/win32.h 2001/02/13 09:30:57
@@ -113,4 +113,21 @@ extern "C++" {
#define WNOHANG -1
+#undef getc
+#undef putc
+#undef fgetc
+#undef fputc
+#undef getchar
+#undef putchar
+#undef fgetchar
+#undef fputchar
+#define getc(_stream) win32_getc(_stream)
+#define putc(_c, _stream) win32_putc(_c, _stream)
+#define fgetc(_stream) getc(_stream)
+#define fputc(_c, _stream) putc(_c, _stream)
+#define getchar() win32_getc(stdin)
+#define putchar(_c) win32_putc(_c, stdout)
+#define fgetchar(_stream) getchar()
+#define fputchar(_c, _stream) putchar(_c)
+
#define access _access
#define chmod _chmod
@@ -428,8 +445,8 @@ HANDLE GetCurrentThreadHandle(void);
int win32_main_context(int arg, void (*handler)(int));
int win32_sleep(unsigned long msec);
-void win32_enter_syscall(void);
-void win32_leave_syscall(void);
-void win32_disable_interrupt(void);
-void win32_enable_interrupt(void);
+void win32_enter_critical(void);
+void win32_leave_critical(void);
+int win32_putc(int, FILE*);
+int win32_getc(FILE*);
#define Sleep(msec) (void)win32_sleep(msec)
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦