* dtable.cc (dtable::find_unused_handle): Fix off-by-one error. Always exit

through the bottom.
(cygwin_attach_handle_to_fd): Make sure that fd tab is locked for the duration
of this function.
* dtable.h (dtable::lock): Make public.
(dtable::unlock): Ditto.
(dtable): Remove friends.
This commit is contained in:
Christopher Faylor 2013-12-01 17:52:48 +00:00
parent 10a5939224
commit f456b9f6f8
3 changed files with 29 additions and 18 deletions

View File

@ -1,3 +1,13 @@
2013-12-01 Christopher Faylor <me.cygwin2013@cgf.cx>
* dtable.cc (dtable::find_unused_handle): Fix off-by-one error. Always
exit through the bottom.
(cygwin_attach_handle_to_fd): Make sure that fd tab is locked for the
duration of this function.
* dtable.h (dtable::lock): Make public.
(dtable::unlock): Ditto.
(dtable): Remove friends.
2013-12-01 Corinna Vinschen <corinna@vinschen.de> 2013-12-01 Corinna Vinschen <corinna@vinschen.de>
* dtable.cc (dtable::extend): Change local variable new_size to size_t * dtable.cc (dtable::extend): Change local variable new_size to size_t

View File

@ -223,17 +223,22 @@ dtable::delete_archetype (fhandler_base *fh)
int int
dtable::find_unused_handle (size_t start) dtable::find_unused_handle (size_t start)
{ {
size_t extendby = (start > size) ? start - size : NOFILE_INCR; size_t extendby = (start >= size) ? 1 + start - size : NOFILE_INCR;
/* This do loop should only ever execute twice. */ /* This do loop should only ever execute twice. */
int res = -1;
do do
{ {
for (size_t i = start; i < size; i++) for (size_t i = start; i < size; i++)
/* See if open -- no need for overhead of not_open */ /* See if open -- no need for overhead of not_open */
if (fds[i] == NULL) if (fds[i] == NULL)
return i; {
res = (int) i;
break;
}
} }
while (extend (extendby)); while (extend (extendby));
return -1; return res;
} }
void void
@ -251,14 +256,19 @@ extern "C" int
cygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin, cygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin,
DWORD myaccess) DWORD myaccess)
{ {
cygheap->fdtab.lock ();
if (fd == -1) if (fd == -1)
fd = cygheap->fdtab.find_unused_handle (); fd = cygheap->fdtab.find_unused_handle ();
fhandler_base *fh = build_fh_name (name); fhandler_base *fh = build_fh_name (name);
if (!fh) if (!fh)
return -1; fd = -1;
cygheap->fdtab[fd] = fh; else
cygheap->fdtab[fd]->inc_refcnt (); {
fh->init (handle, myaccess, bin ?: fh->pc_binmode ()); cygheap->fdtab[fd] = fh;
cygheap->fdtab[fd]->inc_refcnt ();
fh->init (handle, myaccess, bin ?: fh->pc_binmode ());
}
cygheap->fdtab.unlock ();
return fd; return fd;
} }

View File

@ -34,8 +34,6 @@ class dtable
static const int initial_archetype_size = 8; static const int initial_archetype_size = 8;
size_t first_fd_for_open; size_t first_fd_for_open;
int cnt_need_fixup_before; int cnt_need_fixup_before;
void lock () {lock_process::locker.acquire ();}
void unlock () {lock_process::locker.release ();}
public: public:
size_t size; size_t size;
@ -87,15 +85,8 @@ public:
void delete_archetype (fhandler_base *); void delete_archetype (fhandler_base *);
void fixup_before_exec (DWORD win_proc_id); void fixup_before_exec (DWORD win_proc_id);
void fixup_before_fork (DWORD win_proc_id); void fixup_before_fork (DWORD win_proc_id);
friend void dtable_init (); void lock () {lock_process::locker.acquire ();}
friend void __stdcall close_all_files (bool); void unlock () {lock_process::locker.release ();}
friend int dup_finish (int, int, int);
friend class fhandler_base;
friend class cygheap_fdmanip;
friend class cygheap_fdget;
friend class cygheap_fdnew;
friend class cygheap_fdenum;
friend class lock_process;
}; };
fhandler_base *build_fh_dev (const device&, const char * = NULL); fhandler_base *build_fh_dev (const device&, const char * = NULL);