This is the mail archive of the cygwin-patches@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] system-cancel part2


On Wed, Jan 15, 2003 at 12:23:14PM +0100, Thomas Pfaff wrote:
>
>This patch will make sure that the signal handlers that are saved in the
>system call are restored even if the thread got cancelled. Since
>spawn_guts uses waitpid when mode is _P_WAIT spawn_guts is a cancellation
>point.
>
>Attached is the patch and a new test case.
>
>2003-01-15  Thomas Paff  <tpfaff@gmx.net>
>
>	* syscalls.cc (struct system_cleanup_args): New struct.
>	(system_cleanup): New function.
>	(system): Use pthread_cleanup_push and _pop to save and restore
>	signal handlers and sigprocmask.

Please do not check this in.  You are changing other parts of the code than the
pthreads code and I want to study what you've done before you are approved to
check this in.

In other words, Robert's "as long as you have a test case" only applies to
trivial changes or changes to pthread.cc, thread.cc, or thread.h.

cgf

>diff -urp src.old/winsup/cygwin/syscalls.cc src/winsup/cygwin/syscalls.cc
>--- src.old/winsup/cygwin/syscalls.cc	2003-01-14 11:35:51.000000000 +0100
>+++ src/winsup/cygwin/syscalls.cc	2003-01-15 09:42:04.000000000 +0100
>@@ -1371,6 +1371,21 @@ done:
>   return res;
> }
> 
>+struct system_cleanup_args
>+{
>+  _sig_func_ptr oldint, oldquit;
>+  sigset_t old_mask;
>+};
>+
>+static void system_cleanup (void *args)
>+{
>+  struct system_cleanup_args *cleanup_args = (struct system_cleanup_args *) args;
>+
>+  signal (SIGINT, cleanup_args->oldint);
>+  signal (SIGQUIT, cleanup_args->oldquit);
>+  (void) sigprocmask (SIG_SETMASK, &cleanup_args->old_mask, 0);
>+}  
>+
> extern "C" int
> system (const char *cmdstring)
> {
>@@ -1382,23 +1397,25 @@ system (const char *cmdstring)
>   sigframe thisframe (mainthread);
>   int res;
>   const char* command[4];
>-  _sig_func_ptr oldint, oldquit;
>-  sigset_t child_block, old_mask;
>+  struct system_cleanup_args cleanup_args;
>+  sigset_t child_block;
> 
>   if (cmdstring == (const char *) NULL)
> 	return 1;
> 
>-  oldint = signal (SIGINT, SIG_IGN);
>-  oldquit = signal (SIGQUIT, SIG_IGN);
>+  cleanup_args.oldint = signal (SIGINT, SIG_IGN);
>+  cleanup_args.oldquit = signal (SIGQUIT, SIG_IGN);
>   sigemptyset (&child_block);
>   sigaddset (&child_block, SIGCHLD);
>-  (void) sigprocmask (SIG_BLOCK, &child_block, &old_mask);
>+  (void) sigprocmask (SIG_BLOCK, &child_block, &cleanup_args.old_mask);
> 
>   command[0] = "sh";
>   command[1] = "-c";
>   command[2] = cmdstring;
>   command[3] = (const char *) NULL;
> 
>+  pthread_cleanup_push (system_cleanup, (void *) &cleanup_args);
>+
>   if ((res = spawnvp (_P_WAIT, "sh", command)) == -1)
>     {
>       // when exec fails, return value should be as if shell
>@@ -1406,9 +1423,8 @@ system (const char *cmdstring)
>       res = 127;
>     }
> 
>-  signal (SIGINT, oldint);
>-  signal (SIGQUIT, oldquit);
>-  (void) sigprocmask (SIG_SETMASK, &old_mask, 0);
>+  pthread_cleanup_pop (1);
>+
>   return res;
> }
> 

>/*
> * File: cancel11.c
> *
> * Test Synopsis: Test if system is a cancellation point.
> *
> * Test Method (Validation or Falsification):
> * - 
> *
> * Requirements Tested:
> * -
> *
> * Features Tested:
> * - 
> *
> * Cases Tested:
> * - 
> *
> * Description:
> * - 
> *
> * Environment:
> * - 
> *
> * Input:
> * - None.
> *
> * Output:
> * - File name, Line number, and failed expression on failure.
> * - No output on success.
> *
> * Assumptions:
> * - have working pthread_create, pthread_cancel, pthread_setcancelstate
> *   pthread_join
> *
> * Pass Criteria:
> * - Process returns zero exit status.
> *
> * Fail Criteria:
> * - Process returns non-zero exit status.
> */
>
>#include "test.h"
>
>static void *Thread(void *punused)
>{
>  system ("sleep 10");
>
>  return NULL;
>}
>
>int main (void)
>{
>  void * result;
>  pthread_t t;
>
>  assert (pthread_create (&t, NULL, Thread, NULL) == 0);
>  sleep (5);
>  assert (pthread_cancel (t) == 0);
>  assert (pthread_join (t, &result) == 0);
>  assert (result == PTHREAD_CANCELED);
>
>  return 0;
>}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]