diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 201bc59ea..659e7ae4c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,28 @@ +2014-07-16 Corinna Vinschen + + * thread.cc (pthread::create): Handle stackaddr as upper bound address. + Add comment. + (pthread_attr_setstack): Store upper bound address in stackaddr. + Explain why. + (pthread_attr_getstack): Handle stackaddr as upper bound address. + Add comment. + (pthread_attr_setstackaddr): Add comment. + (pthread_attr_getstackaddr): Add comment. + (pthread_attr_getstacksize): Return default stacksize if stacksize has + not been set by the application, just as on Linux. Add comment. + (pthread_getattr_np): Store upper bound address in stackaddr. Explain + why. + * include/pthread.h: Remove outdated comment. + (pthread_attr_getstackaddr): Mark as deprecated, as on Linux. + (pthread_attr_setstackaddr): Ditto. + +2014-07-15 Christopher Faylor + + * sigproc.cc (sigproc_init): Set aside more buffer space for signal + pipes. + (sig_send): Retry WriteFiles which fail when there is no error but + packbytes have not been sent. + 2014-07-15 Christopher Faylor * sigproc.cc (send_sig): Don't report an error if WriteFile succeeds. diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h index bfedf1f75..9170d96fc 100644 --- a/winsup/cygwin/include/pthread.h +++ b/winsup/cygwin/include/pthread.h @@ -1,7 +1,7 @@ /* pthread.h: POSIX pthread interface Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2011, 2012, 2013 Red Hat, Inc. + 2007, 2011, 2012, 2013, 2014 Red Hat, Inc. Written by Marco Fuykschot @@ -75,7 +75,8 @@ int pthread_attr_getschedparam (const pthread_attr_t *, struct sched_param *); int pthread_attr_getschedpolicy (const pthread_attr_t *, int *); int pthread_attr_getscope (const pthread_attr_t *, int *); int pthread_attr_getstack (const pthread_attr_t *, void **, size_t *); -int pthread_attr_getstackaddr (const pthread_attr_t *, void **); +int pthread_attr_getstackaddr (const pthread_attr_t *, void **) + __attribute__ ((deprecated)); int pthread_attr_init (pthread_attr_t *); int pthread_attr_setdetachstate (pthread_attr_t *, int); int pthread_attr_setguardsize (pthread_attr_t *, size_t); @@ -85,12 +86,9 @@ int pthread_attr_setschedpolicy (pthread_attr_t *, int); int pthread_attr_setscope (pthread_attr_t *, int); #ifdef _POSIX_THREAD_ATTR_STACKADDR -/* These functions may be implementable via some low level trickery. For now they are - * Not supported or implemented. The prototypes are here so if someone greps the - * source they will see these comments - */ int pthread_attr_setstack (pthread_attr_t *, void *, size_t); -int pthread_attr_setstackaddr (pthread_attr_t *, void *); +int pthread_attr_setstackaddr (pthread_attr_t *, void *) + __attribute__ ((deprecated)); #endif #ifdef _POSIX_THREAD_ATTR_STACKSIZE diff --git a/winsup/cygwin/release/1.7.31 b/winsup/cygwin/release/1.7.31 index fad008429..21d91255d 100644 --- a/winsup/cygwin/release/1.7.31 +++ b/winsup/cygwin/release/1.7.31 @@ -8,6 +8,11 @@ What changed: - The default pthread_mutex type is now PTHREAD_MUTEX_NORMAL, rather than PTHREAD_MUTEX_ERRORCHECK, just as on Linux. +- Align pthread_attr stack functions more closely to Linux. + +- Mark pthread_attr_getstackaddr and pthread_attr_setstackaddr as deprecated, + as on Linux. + Bug Fixes --------- diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index a530c89ca..f04c01386 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -426,7 +426,7 @@ sigproc_init () char char_sa_buf[1024]; PSECURITY_ATTRIBUTES sa = sec_user_nih ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid()); DWORD err = fhandler_pipe::create (sa, &my_readsig, &my_sendsig, - sizeof (sigpacket), "sigwait", + NSIG * sizeof (sigpacket), "sigwait", PIPE_ADD_PID); if (err) { @@ -635,7 +635,19 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) } DWORD nb; - if (!WriteFile (sendsig, leader, packsize, &nb, NULL)) + BOOL res; + /* Try multiple times to send if packsize != nb since that probably + means that the pipe buffer is full. */ + for (int i = 0; i < 100; i++) + { + res = WriteFile (sendsig, leader, packsize, &nb, NULL); + if (!res || packsize == nb) + break; + Sleep (10); + res = 0; + } + + if (!res) { /* Couldn't send to the pipe. This probably means that the process is exiting. */ diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 8fdbf3610..fc70c3752 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -473,9 +473,13 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr, arg = threadarg; mutex.lock (); - win32_obj_id = CygwinCreateThread (thread_init_wrapper, this, attr.stackaddr, - attr.stacksize ?: PTHREAD_DEFAULT_STACKSIZE, - attr.guardsize, 0, &thread_id); + /* stackaddr holds the uppermost stack address. See the comments in + pthread_attr_setstack and pthread_attr_setstackaddr for a description. */ + ULONG stacksize = attr.stacksize ?: PTHREAD_DEFAULT_STACKSIZE; + PVOID stackaddr = attr.stackaddr ? ((caddr_t) attr.stackaddr - stacksize) + : NULL; + win32_obj_id = CygwinCreateThread (thread_init_wrapper, this, stackaddr, + stacksize, attr.guardsize, 0, &thread_id); if (!win32_obj_id) { @@ -2253,7 +2257,13 @@ pthread_attr_setstack (pthread_attr_t *attr, void *addr, size_t size) return EINVAL; if (size < PTHREAD_STACK_MIN) return EINVAL; - (*attr)->stackaddr = addr; + /* The incoming address addr points to the lowest addressable byte of a + buffer of size bytes. Due to the way pthread_attr_setstackaddr is defined + on Linux, the lowest address ot the stack can't be reliably computed when + using pthread_attr_setstackaddr/pthread_attr_setstacksize. Therefore we + store the uppermost address of the stack in stackaddr. See also the + comment in pthread_attr_setstackaddr. */ + (*attr)->stackaddr = (caddr_t) addr + size; (*attr)->stacksize = size; return 0; } @@ -2263,7 +2273,9 @@ pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size) { if (!pthread_attr::is_good_object (attr)) return EINVAL; - *addr = (*attr)->stackaddr; + /* stackaddr holds the uppermost stack address. See the comment in + pthread_attr_setstack. */ + *addr = (caddr_t) (*attr)->stackaddr - (*attr)->stacksize; *size = (*attr)->stacksize; return 0; } @@ -2275,6 +2287,12 @@ pthread_attr_setstackaddr (pthread_attr_t *attr, void *addr) return EINVAL; if (addr == NULL) return EINVAL; + /* This function is deprecated in SUSv4, but SUSv3 didn't define + if the incoming stack address is the lowest address of the memory + area defined as stack, or if it's the start address of the stack + at which it begins its growth. On Linux it's the latter which + means the uppermost stack address on x86 based systems. See comment + in pthread_attr_setstack as well. */ (*attr)->stackaddr = addr; return 0; } @@ -2284,6 +2302,7 @@ pthread_attr_getstackaddr (const pthread_attr_t *attr, void **addr) { if (!pthread_attr::is_good_object (attr)) return EINVAL; + /* See comment in pthread_attr_setstackaddr. */ *addr = (*attr)->stackaddr; return 0; } @@ -2304,7 +2323,10 @@ pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size) { if (!pthread_attr::is_good_object (attr)) return EINVAL; - *size = (*attr)->stacksize; + /* If the stacksize has not been set by the application, return the + default stacksize. Note that this is different from what + pthread_attr_getstack returns. */ + *size = (*attr)->stacksize ?: PTHREAD_DEFAULT_STACKSIZE; return 0; } @@ -2486,10 +2508,12 @@ pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) if (NT_SUCCESS (status)) { PTEB teb = (PTEB) tbi->TebBaseAddress; - (*attr)->stackaddr = teb->DeallocationStack ?: teb->Tib.StackLimit; - /* stack grows downwards on x86 systems */ + /* stackaddr holds the uppermost stack address. See the comments + in pthread_attr_setstack and pthread_attr_setstackaddr for a + description. */ + (*attr)->stackaddr = teb->Tib.StackBase; (*attr)->stacksize = (uintptr_t) teb->Tib.StackBase - - (uintptr_t) (*attr)->stackaddr; + - (uintptr_t) (teb->DeallocationStack ?: teb->Tib.StackLimit); } else {