* thread.cc: Remove temporary newlib workaround, now that newlib
handles thread cancellation by itself. (class __cygwin_lock_handler): Remove. (__cygwin_lock_cleanup): Remove. (__cygwin_lock_lock): Revert newlib workaround, (__cygwin_lock_trylock): Ditto. (__cygwin_lock_unlock): Ditto. (pthread::pop_cleanup_handler): Ditto.
This commit is contained in:
		| @@ -1,3 +1,14 @@ | ||||
| 2012-05-30  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* thread.cc: Remove temporary newlib workaround, now that newlib | ||||
| 	handles thread cancellation by itself. | ||||
| 	(class __cygwin_lock_handler): Remove. | ||||
| 	(__cygwin_lock_cleanup): Remove. | ||||
| 	(__cygwin_lock_lock): Revert newlib workaround, | ||||
| 	(__cygwin_lock_trylock): Ditto. | ||||
| 	(__cygwin_lock_unlock): Ditto. | ||||
| 	(pthread::pop_cleanup_handler): Ditto. | ||||
|  | ||||
| 2012-05-29  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* select.cc (select_stuff::wait): Temporarily disable restarting | ||||
|   | ||||
| @@ -95,95 +95,23 @@ __cygwin_lock_fini (_LOCK_T *lock) | ||||
|   pthread_mutex_destroy ((pthread_mutex_t*) lock); | ||||
| } | ||||
|  | ||||
| #define WORKAROUND_NEWLIB | ||||
|  | ||||
| #ifdef WORKAROUND_NEWLIB | ||||
| /* FIXME: | ||||
|  | ||||
|    This cleanup stuff is necessary to harden Cygwin against thread | ||||
|    cancellation.  In theory, installing a cleanup handler is the task of | ||||
|    the calling function. | ||||
|  | ||||
|    The problem here is that a lot of calling functions are in newlib's | ||||
|    stdio implementation.  So, the right thing to do would be to change | ||||
|    newlib's stdio functions to install the required pthread cleanup | ||||
|    handlers. | ||||
|  | ||||
|    This is a bigger task than it sounds, so, as a temporary workaround, | ||||
|    what we do here is to install a cleanup handler in the lock function | ||||
|    itself and to cleanup in the unlock function.  This works around the | ||||
|    problem for the time being. */ | ||||
| class __cygwin_lock_handler : public __pthread_cleanup_handler | ||||
| { | ||||
| public: | ||||
|   pthread_mutex_t *lock; | ||||
|  | ||||
|   __cygwin_lock_handler (__cleanup_routine_type _fn, _LOCK_T *_lock) | ||||
|   { | ||||
|     function = _fn; | ||||
|     arg = this; | ||||
|     next = NULL; | ||||
|     lock = (pthread_mutex_t *) _lock; | ||||
|   } | ||||
|   void *operator new (size_t) __attribute__ ((nothrow)) | ||||
|   {return cmalloc (HEAP_BUF, sizeof (__cygwin_lock_handler));} | ||||
|   void operator delete (void *p) { cfree (p); } | ||||
| }; | ||||
|  | ||||
| static void | ||||
| __cygwin_lock_cleanup (void *hdl) | ||||
| { | ||||
|   __cygwin_lock_handler *cleanup = (__cygwin_lock_handler *) hdl; | ||||
|   pthread_mutex_unlock (cleanup->lock); | ||||
|   delete cleanup; | ||||
| } | ||||
| #endif /* WORKAROUND_NEWLIB */ | ||||
|  | ||||
| extern "C" void | ||||
| __cygwin_lock_lock (_LOCK_T *lock) | ||||
| { | ||||
|   paranoid_printf ("threadcount %d.  locking", MT_INTERFACE->threadcount); | ||||
| #ifdef WORKAROUND_NEWLIB | ||||
|   if (cygwin_finished_initializing) | ||||
|     { | ||||
|       __cygwin_lock_handler *cleanup | ||||
| 	= new __cygwin_lock_handler (__cygwin_lock_cleanup, lock); | ||||
|       pthread::self ()->push_cleanup_handler (cleanup); | ||||
|     } | ||||
| #endif /* WORKAROUND_NEWLIB */ | ||||
|   pthread_mutex_lock ((pthread_mutex_t*) lock); | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| __cygwin_lock_trylock (_LOCK_T *lock) | ||||
| { | ||||
| #ifdef WORKAROUND_NEWLIB | ||||
|   if (cygwin_finished_initializing) | ||||
|     { | ||||
|       __cygwin_lock_handler *cleanup | ||||
|       	= new __cygwin_lock_handler (__cygwin_lock_cleanup, lock); | ||||
|       pthread::self ()->push_cleanup_handler (cleanup); | ||||
|       int ret = pthread_mutex_trylock ((pthread_mutex_t*) lock); | ||||
|       if (ret) | ||||
| 	{ | ||||
| 	  pthread::self ()->pop_cleanup_handler (0); | ||||
| 	  delete cleanup; | ||||
| 	} | ||||
|       return ret; | ||||
|     } | ||||
|   else | ||||
| #endif /* WORKAROUND_NEWLIB */ | ||||
|   return pthread_mutex_trylock ((pthread_mutex_t*) lock); | ||||
| } | ||||
|  | ||||
|  | ||||
| extern "C" void | ||||
| __cygwin_lock_unlock (_LOCK_T *lock) | ||||
| { | ||||
| #ifdef WORKAROUND_NEWLIB | ||||
|   if (cygwin_finished_initializing) | ||||
|     pthread::self ()->pop_cleanup_handler (1); | ||||
|   else | ||||
| #endif /* WORKAROUND_NEWLIB */ | ||||
|   pthread_mutex_unlock ((pthread_mutex_t*) lock); | ||||
|   paranoid_printf ("threadcount %d.  unlocked", MT_INTERFACE->threadcount); | ||||
| } | ||||
| @@ -1159,22 +1087,10 @@ pthread::pop_cleanup_handler (int const execute) | ||||
|   if (cleanup_stack != NULL) | ||||
|     { | ||||
|       __pthread_cleanup_handler *handler = cleanup_stack; | ||||
| #ifdef WORKAROUND_NEWLIB | ||||
|       /* We split out handler->next so we can set cleanup_stack to handler->next | ||||
| 	 without relying on handler still existing.  This allows to delete the | ||||
| 	 handler in the handler function.  For a description why we need that, | ||||
| 	 at least temporarly, see the comment preceeding the definition of | ||||
| 	 __cygwin_lock_handler earlier in this file. */ | ||||
|       __pthread_cleanup_handler *next = handler->next; | ||||
|  | ||||
|       if (execute) | ||||
| 	(*handler->function) (handler->arg); | ||||
|       cleanup_stack = next; | ||||
| #else | ||||
|       if (execute) | ||||
| 	(*handler->function) (handler->arg); | ||||
|       cleanup_stack = handler->next; | ||||
| #endif /* WORKAROUND_NEWLIB */ | ||||
|     } | ||||
|  | ||||
|   mutex.unlock (); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user