* win32/win32.c (flock): supports larger files, and maps error

code.

* win32/win32.c (rb_w32_asynchronize): returns errno from child
  thread.

* win32/win32.c (rb_w32_fclose, rb_w32_close): ensures unlocked.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2003-02-28 13:54:14 +00:00
parent f649db5b16
commit 801406cb5d
2 changed files with 38 additions and 33 deletions

View File

@ -1,3 +1,13 @@
Fri Feb 28 22:54:10 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* win32/win32.c (flock): supports larger files, and maps error
code.
* win32/win32.c (rb_w32_asynchronize): returns errno from child
thread.
* win32/win32.c (rb_w32_fclose, rb_w32_close): ensures unlocked.
Wed Feb 26 17:38:16 2003 Tanaka Akira <akr@m17n.org> Wed Feb 26 17:38:16 2003 Tanaka Akira <akr@m17n.org>
* lib/open-uri.rb: replace Kernel.open as well. * lib/open-uri.rb: replace Kernel.open as well.

View File

@ -159,8 +159,8 @@ HANDLE GetCurrentThreadHandle(void)
/* simulate flock by locking a range on the file */ /* simulate flock by locking a range on the file */
#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError())) #define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError() == ERROR_LOCK_VIOLATION ? EWOULDBLOCK : EACCES))
#define LK_LEN 0xffff0000 #define LK_LEN ULONG_MAX
static VALUE static VALUE
flock_winnt(VALUE self, int argc, VALUE* argv) flock_winnt(VALUE self, int argc, VALUE* argv)
@ -174,31 +174,21 @@ flock_winnt(VALUE self, int argc, VALUE* argv)
switch(oper) { switch(oper) {
case LOCK_SH: /* shared lock */ case LOCK_SH: /* shared lock */
LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o), i); LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, LK_LEN, &o), i);
break; break;
case LOCK_EX: /* exclusive lock */ case LOCK_EX: /* exclusive lock */
LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o), i); LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, LK_LEN, &o), i);
break; break;
case LOCK_SH|LOCK_NB: /* non-blocking shared lock */ case LOCK_SH|LOCK_NB: /* non-blocking shared lock */
LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o), i); LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, LK_LEN, &o), i);
break; break;
case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */ case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */
LK_ERR(LockFileEx(fh, LK_ERR(LockFileEx(fh,
LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
0, LK_LEN, 0, &o), i); 0, LK_LEN, LK_LEN, &o), i);
if (errno == EDOM)
errno = EWOULDBLOCK;
break; break;
case LOCK_UN: /* unlock lock */ case LOCK_UN: /* unlock lock */
if (UnlockFileEx(fh, 0, LK_LEN, 0, &o)) { LK_ERR(UnlockFileEx(fh, 0, LK_LEN, LK_LEN, &o), i);
i = 0;
if (errno == EDOM)
errno = EWOULDBLOCK;
}
else {
/* GetLastError() must returns `ERROR_NOT_LOCKED' */
errno = EWOULDBLOCK;
}
break; break;
default: /* unknown */ default: /* unknown */
errno = EINVAL; errno = EINVAL;
@ -217,20 +207,15 @@ flock_win95(VALUE self, int argc, VALUE* argv)
switch(oper) { switch(oper) {
case LOCK_EX: case LOCK_EX:
while(i == -1) { do {
LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i); LK_ERR(LockFile(fh, 0, 0, LK_LEN, LK_LEN), i);
if (errno != EDOM && i == -1) break; } while (i && errno == EWOULDBLOCK);
}
break; break;
case LOCK_EX | LOCK_NB: case LOCK_EX|LOCK_NB:
LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i); LK_ERR(LockFile(fh, 0, 0, LK_LEN, LK_LEN), i);
if (errno == EDOM)
errno = EWOULDBLOCK;
break; break;
case LOCK_UN: case LOCK_UN:
LK_ERR(UnlockFile(fh, 0, 0, LK_LEN, 0), i); LK_ERR(UnlockFile(fh, 0, 0, LK_LEN, LK_LEN), i);
if (errno == EDOM)
errno = EWOULDBLOCK;
break; break;
default: default:
errno = EINVAL; errno = EINVAL;
@ -241,7 +226,6 @@ flock_win95(VALUE self, int argc, VALUE* argv)
#endif #endif
#undef LK_ERR #undef LK_ERR
#undef LK_LEN
int int
flock(int fd, int oper) flock(int fd, int oper)
@ -2950,6 +2934,7 @@ int rb_w32_putc(int c, FILE* stream)
struct asynchronous_arg_t { struct asynchronous_arg_t {
/* output field */ /* output field */
void* stackaddr; void* stackaddr;
int errnum;
/* input field */ /* input field */
VALUE (*func)(VALUE self, int argc, VALUE* argv); VALUE (*func)(VALUE self, int argc, VALUE* argv);
@ -2961,13 +2946,17 @@ struct asynchronous_arg_t {
static DWORD WINAPI static DWORD WINAPI
call_asynchronous(PVOID argp) call_asynchronous(PVOID argp)
{ {
DWORD ret;
struct asynchronous_arg_t *arg = argp; struct asynchronous_arg_t *arg = argp;
arg->stackaddr = &argp; arg->stackaddr = &argp;
return (DWORD)arg->func(arg->self, arg->argc, arg->argv); ret = (DWORD)arg->func(arg->self, arg->argc, arg->argv);
arg->errnum = errno;
return ret;
} }
VALUE rb_w32_asynchronize(asynchronous_func_t func, VALUE
VALUE self, int argc, VALUE* argv, VALUE intrval) rb_w32_asynchronize(asynchronous_func_t func, VALUE self,
int argc, VALUE* argv, VALUE intrval)
{ {
DWORD val; DWORD val;
BOOL interrupted = FALSE; BOOL interrupted = FALSE;
@ -2977,6 +2966,7 @@ VALUE rb_w32_asynchronize(asynchronous_func_t func,
struct asynchronous_arg_t arg; struct asynchronous_arg_t arg;
arg.stackaddr = NULL; arg.stackaddr = NULL;
arg.errnum = 0;
arg.func = func; arg.func = func;
arg.self = self; arg.self = self;
arg.argc = argc; arg.argc = argc;
@ -3011,6 +3001,10 @@ VALUE rb_w32_asynchronize(asynchronous_func_t func,
Debug(fprintf(stderr, "couldn't release stack:%p:%d\n", Debug(fprintf(stderr, "couldn't release stack:%p:%d\n",
m.AllocationBase, GetLastError())); m.AllocationBase, GetLastError()));
} }
errno = EINTR;
}
else {
errno = arg.errnum;
} }
} }
}); });
@ -3020,7 +3014,6 @@ VALUE rb_w32_asynchronize(asynchronous_func_t func,
} }
if (interrupted) { if (interrupted) {
errno = EINTR;
CHECK_INTS; CHECK_INTS;
} }
@ -3086,6 +3079,7 @@ rb_w32_fclose(FILE *fp)
if (fflush(fp)) return -1; if (fflush(fp)) return -1;
if (!is_socket(sock)) { if (!is_socket(sock)) {
UnlockFile((HANDLE)sock, 0, 0, LK_LEN, LK_LEN);
return fclose(fp); return fclose(fp);
} }
_set_osfhnd(fd, (SOCKET)INVALID_HANDLE_VALUE); _set_osfhnd(fd, (SOCKET)INVALID_HANDLE_VALUE);
@ -3103,6 +3097,7 @@ rb_w32_close(int fd)
SOCKET sock = TO_SOCKET(fd); SOCKET sock = TO_SOCKET(fd);
if (!is_socket(sock)) { if (!is_socket(sock)) {
UnlockFile((HANDLE)sock, 0, 0, LK_LEN, LK_LEN);
return _close(fd); return _close(fd);
} }
if (closesocket(sock) == SOCKET_ERROR) { if (closesocket(sock) == SOCKET_ERROR) {