* cygthread.cc (cygthread::initialized): Avoid copying on fork or some threads

may not end up in the pool.
(cygthread::new): Avoid race when checking for initialized.  Add debugging
code.
* fhandler.cc (fhandler_base::raw_read): Add case for ERROR_INVALID_HANDLE due
to Win95 directories.
(fhandler_base::open): Handle errors due to Win95 directories.
(fhandler_base::close): Add get_nohandle () test.
(fhandler_base::set_close_on_exec): Ditto.
(fhandler_base::fork_fixup): Ditto.
(fhandler_base::lock): Change error code to Posix EINVAL.
(fhandler_base::dup): If get_nohandle (), set new value to INVALID_HANDLE_VALUE
instead of NULL.
* fhandler_disk_file.cc (fhandler_disk_file::fstat): Call fstat_by_name if
get_nohandle ().  Remove extraneous element from strpbrk.
(fhandler_disk_file::open): Remove test for Win95 directory.
* fhandler_random.cc (fhandler_dev_random::open): Add set_nohandle ().
* fhandler_clipboard.cc (fhandler_dev_clipboard::open): Ditto.
* fhandler_zero.cc (fhandler_dev_zero::open): Ditto.
(fhandler_dev_zero::close): Delete.
* fhandler.h (class fhandler_dev_zero): Ditto.
This commit is contained in:
Christopher Faylor 2002-09-19 03:30:20 +00:00
parent 57dfd574a7
commit 5bf785a017
20 changed files with 152 additions and 111 deletions

View File

@ -1,3 +1,31 @@
2002-09-18 Christopher Faylor <cgf@redhat.com>
* cygthread.cc (cygthread::initialized): Avoid copying on fork or some
threads may not end up in the pool.
(cygthread::new): Avoid race when checking for initialized. Add
debugging code.
2002-09-18 Pierre Humblet <pierre.humblet@ieee.org>
* fhandler.cc (fhandler_base::raw_read): Add case for
ERROR_INVALID_HANDLE due to Win95 directories.
(fhandler_base::open): Handle errors due to Win95 directories.
(fhandler_base::close): Add get_nohandle () test.
(fhandler_base::set_close_on_exec): Ditto.
(fhandler_base::fork_fixup): Ditto.
(fhandler_base::lock): Change error code to Posix EINVAL.
(fhandler_base::dup): If get_nohandle (), set new value to
INVALID_HANDLE_VALUE instead of NULL.
* fhandler_disk_file.cc (fhandler_disk_file::fstat): Call fstat_by_name
if get_nohandle (). Remove extraneous element from strpbrk.
(fhandler_disk_file::open): Remove test for Win95 directory.
* fhandler_random.cc (fhandler_dev_random::open): Add set_nohandle ().
* fhandler_clipboard.cc (fhandler_dev_clipboard::open): Ditto.
* fhandler_zero.cc (fhandler_dev_zero::open): Ditto.
(fhandler_dev_zero::close): Delete.
* fhandler.h (class fhandler_dev_zero): Ditto.
2002-09-17 Robert Collins <rbtcollins@hotmail.com> 2002-09-17 Robert Collins <rbtcollins@hotmail.com>
* thread.cc (pthread_key::set): Preserve GetLastError(). Reported * thread.cc (pthread_key::set): Preserve GetLastError(). Reported

View File

@ -19,7 +19,7 @@ static cygthread NO_COPY threads[6];
#define NTHREADS (sizeof (threads) / sizeof (threads[0])) #define NTHREADS (sizeof (threads) / sizeof (threads[0]))
DWORD NO_COPY cygthread::main_thread_id; DWORD NO_COPY cygthread::main_thread_id;
bool cygthread::initialized; bool NO_COPY cygthread::initialized;
/* Initial stub called by cygthread constructor. Performs initial /* Initial stub called by cygthread constructor. Performs initial
per-thread initialization and loops waiting for new thread functions per-thread initialization and loops waiting for new thread functions
@ -127,8 +127,9 @@ new (size_t)
for (;;) for (;;)
{ {
bool was_initialized = initialized;
/* Search the threads array for an empty slot to use */ /* Search the threads array for an empty slot to use */
for (info = threads; info < threads + NTHREADS; info++) for (info = threads + NTHREADS - 1; info >= threads; info--)
if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0))) if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0)))
{ {
info->id = id; info->id = id;
@ -139,12 +140,19 @@ new (size_t)
return info; return info;
} }
if (!initialized) if (!was_initialized)
Sleep (0); /* thread_runner is not be finished yet. */ Sleep (0); /* thread_runner is not finished yet. */
else else
{
#ifdef DEBUGGING
char buf[1024];
if (GetEnvironmentVariable ("CYGWIN_NOFREERANGE", buf, sizeof (buf)))
api_fatal ("Overflowed cygwin thread pool");
#endif
return freerange (); return freerange ();
} }
} }
}
cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param, cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param,
const char *name): func (start), arg (param) const char *name): func (start), arg (param)

View File

@ -234,8 +234,8 @@ fhandler_base::set_flags (int flags, int supplied_bin)
else if (supplied_bin) else if (supplied_bin)
bin = supplied_bin; bin = supplied_bin;
else else
bin = get_w_binary () || get_r_binary () || (binmode != O_TEXT) ? bin = get_w_binary () || get_r_binary () || (binmode != O_TEXT)
O_BINARY : O_TEXT; ? O_BINARY : O_TEXT;
openflags = flags | bin; openflags = flags | bin;
@ -275,6 +275,7 @@ fhandler_base::raw_read (void *ptr, size_t ulen)
return 0; return 0;
case ERROR_INVALID_FUNCTION: case ERROR_INVALID_FUNCTION:
case ERROR_INVALID_PARAMETER: case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_HANDLE:
if (openflags & O_DIROPEN) if (openflags & O_DIROPEN)
{ {
set_errno (EISDIR); set_errno (EISDIR);
@ -441,10 +442,20 @@ fhandler_base::open (path_conv *pc, int flags, mode_t mode)
if (x == INVALID_HANDLE_VALUE) if (x == INVALID_HANDLE_VALUE)
{ {
if (GetLastError () == ERROR_INVALID_HANDLE) if (pc->isdir () && !wincap.can_open_directories ())
{
if (mode & (O_CREAT | O_EXCL) == (O_CREAT | O_EXCL))
set_errno (EEXIST);
else if (mode & (O_WRONLY | O_RDWR))
set_errno (EISDIR);
else
set_nohandle (true);
}
else if (GetLastError () == ERROR_INVALID_HANDLE)
set_errno (ENOENT); set_errno (ENOENT);
else else
__seterrno (); __seterrno ();
if (!get_nohandle ())
goto done; goto done;
} }
@ -871,7 +882,7 @@ fhandler_base::close ()
int res = -1; int res = -1;
syscall_printf ("closing '%s' handle %p", get_name (), get_handle()); syscall_printf ("closing '%s' handle %p", get_name (), get_handle());
if (CloseHandle (get_handle())) if (get_nohandle () || CloseHandle (get_handle()))
res = 0; res = 0;
else else
{ {
@ -898,7 +909,7 @@ fhandler_base::ioctl (unsigned int cmd, void *buf)
int int
fhandler_base::lock (int, struct flock *) fhandler_base::lock (int, struct flock *)
{ {
set_errno (ENOSYS); set_errno (EINVAL);
return -1; return -1;
} }
@ -996,7 +1007,7 @@ fhandler_base::dup (fhandler_base *child)
HANDLE nh; HANDLE nh;
if (get_nohandle ()) if (get_nohandle ())
nh = NULL; nh = INVALID_HANDLE_VALUE;
else if (!DuplicateHandle (hMainProc, get_handle(), hMainProc, &nh, 0, TRUE, else if (!DuplicateHandle (hMainProc, get_handle(), hMainProc, &nh, 0, TRUE,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
@ -1207,6 +1218,7 @@ fhandler_base::fork_fixup (HANDLE parent, HANDLE &h, const char *name)
void void
fhandler_base::set_close_on_exec (int val) fhandler_base::set_close_on_exec (int val)
{ {
if (!get_nohandle ())
set_inheritance (io_handle, val); set_inheritance (io_handle, val);
set_close_on_exec_flag (val); set_close_on_exec_flag (val);
debug_printf ("set close_on_exec for %s to %d", get_name (), val); debug_printf ("set close_on_exec for %s to %d", get_name (), val);
@ -1216,6 +1228,7 @@ void
fhandler_base::fixup_after_fork (HANDLE parent) fhandler_base::fixup_after_fork (HANDLE parent)
{ {
debug_printf ("inheriting '%s' from parent", get_name ()); debug_printf ("inheriting '%s' from parent", get_name ());
if (!get_nohandle ())
fork_fixup (parent, io_handle, "io_handle"); fork_fixup (parent, io_handle, "io_handle");
} }

View File

@ -954,7 +954,6 @@ class fhandler_dev_zero: public fhandler_base
int write (const void *ptr, size_t len); int write (const void *ptr, size_t len);
int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3)));
__off64_t lseek (__off64_t offset, int whence); __off64_t lseek (__off64_t offset, int whence);
int close (void);
void dump (); void dump ();
}; };

View File

@ -73,6 +73,7 @@ fhandler_dev_clipboard::open (path_conv *, int flags, mode_t)
membuffer = NULL; membuffer = NULL;
if (!cygnativeformat) if (!cygnativeformat)
cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE);
set_nohandle (true);
set_open_status (); set_open_status ();
return 1; return 1;
} }

View File

@ -156,8 +156,12 @@ fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
bool query_open_already; bool query_open_already;
if (get_io_handle ()) if (get_io_handle ())
{
if (get_nohandle ())
return fstat_by_name (buf, pc);
else
return fstat_by_handle (buf, pc); return fstat_by_handle (buf, pc);
}
/* If we don't care if the file is executable or we already know if it is, /* If we don't care if the file is executable or we already know if it is,
then just do a "query open" as it is apparently much faster. */ then just do a "query open" as it is apparently much faster. */
if (pc->exec_state () != dont_know_if_executable) if (pc->exec_state () != dont_know_if_executable)
@ -166,7 +170,7 @@ fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
query_open_already = false; query_open_already = false;
if (query_open_already && strncasematch (pc->volname (), "FAT", 3) if (query_open_already && strncasematch (pc->volname (), "FAT", 3)
&& !strpbrk (get_win32_name (), "?*|<>|")) && !strpbrk (get_win32_name (), "?*|<>"))
oret = 0; oret = 0;
else if (!(oret = open (pc, open_flags, 0))) else if (!(oret = open (pc, open_flags, 0)))
{ {
@ -191,7 +195,7 @@ fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
} }
} }
if (!oret) if (!oret || get_nohandle ())
res = fstat_by_name (buf, pc); res = fstat_by_name (buf, pc);
else else
{ {
@ -363,15 +367,7 @@ fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode)
set_has_acls (real_path->has_acls ()); set_has_acls (real_path->has_acls ());
set_isremote (real_path->isremote ()); set_isremote (real_path->isremote ());
int res; int res = this->fhandler_base::open (real_path, flags | O_DIROPEN, mode);
if (!real_path->isdir () || wincap.can_open_directories ())
res = this->fhandler_base::open (real_path, flags | O_DIROPEN, mode);
else
{
set_errno (EISDIR);
res = 0;
}
if (!res) if (!res)
goto out; goto out;

View File

@ -32,6 +32,7 @@ int
fhandler_dev_random::open (path_conv *, int flags, mode_t) fhandler_dev_random::open (path_conv *, int flags, mode_t)
{ {
set_flags ((flags & ~O_TEXT) | O_BINARY); set_flags ((flags & ~O_TEXT) | O_BINARY);
set_nohandle (true);
set_open_status (); set_open_status ();
return 1; return 1;
} }

View File

@ -24,6 +24,7 @@ int
fhandler_dev_zero::open (path_conv *, int flags, mode_t) fhandler_dev_zero::open (path_conv *, int flags, mode_t)
{ {
set_flags ((flags & ~O_TEXT) | O_BINARY); set_flags ((flags & ~O_TEXT) | O_BINARY);
set_nohandle (true);
set_open_status (); set_open_status ();
return 1; return 1;
} }
@ -47,12 +48,6 @@ fhandler_dev_zero::lseek (__off64_t, int)
return 0; return 0;
} }
int
fhandler_dev_zero::close (void)
{
return 0;
}
void void
fhandler_dev_zero::dump () fhandler_dev_zero::dump ()
{ {

View File

@ -113,7 +113,7 @@ strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap)
static NO_COPY int nonewline = FALSE; static NO_COPY int nonewline = FALSE;
DWORD err = GetLastError (); DWORD err = GetLastError ();
const char *tn = cygthread::name (); const char *tn = cygthread::name ();
char *pn = __progname ?: myself->progname; char *pn = __progname ?: (myself ? myself->progname : NULL);
int microsec = microseconds (); int microsec = microseconds ();
lmicrosec = microsec; lmicrosec = microsec;