[haiku-commits] r41698 - in haiku/branches/developer/bonefish/signals: headers/private/kernel headers/private/system src/system/kernel

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 24 May 2011 02:51:44 +0200 (CEST)

Author: bonefish
Date: 2011-05-24 02:51:44 +0200 (Tue, 24 May 2011)
New Revision: 41698
Changeset: https://dev.haiku-os.org/changeset/41698

Modified:
   haiku/branches/developer/bonefish/signals/headers/private/kernel/ksignal.h
   
haiku/branches/developer/bonefish/signals/headers/private/system/signal_defs.h
   haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp
   haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp
Log:
Removed the SIGNAL_FLAG_DONT_RESTART_SYSCALL flag entirely and introduced the
kernel internal signal SIGNAL_CONTINUE_THREAD, which is used by resume_thread()
instead. This prevents the Haiku thread management from interfering with POSIX
semantics.



Modified: 
haiku/branches/developer/bonefish/signals/headers/private/kernel/ksignal.h
===================================================================
--- haiku/branches/developer/bonefish/signals/headers/private/kernel/ksignal.h  
2011-05-23 23:30:59 UTC (rev 41697)
+++ haiku/branches/developer/bonefish/signals/headers/private/kernel/ksignal.h  
2011-05-24 00:51:44 UTC (rev 41698)
@@ -36,7 +36,11 @@
 
 #define SYSCALL_RESTART_PARAMETER_SIZE 32
 
+// Kernel internal signal to continue a thread. Used by resume_thread().
+// Non-blockable, prevents syscall restart.
+#define SIGNAL_CONTINUE_THREAD 64
 
+
 struct signal_frame_data {
        siginfo_t       info;
        ucontext_t      context;

Modified: 
haiku/branches/developer/bonefish/signals/headers/private/system/signal_defs.h
===================================================================
--- 
haiku/branches/developer/bonefish/signals/headers/private/system/signal_defs.h  
    2011-05-23 23:30:59 UTC (rev 41697)
+++ 
haiku/branches/developer/bonefish/signals/headers/private/system/signal_defs.h  
    2011-05-24 00:51:44 UTC (rev 41698)
@@ -22,12 +22,10 @@
 #define MAX_SIGNAL_NUMBER                      SIGNAL_REALTIME_MAX
 
 // additional send_signal_etc() flags
-#define SIGNAL_FLAG_DONT_RESTART_SYSCALL       (0x10000)
-       // don't restart the syscall interrupted by the signal (in-kernel use 
only)
-#define SIGNAL_FLAG_QUEUING_REQUIRED           (0x20000)
+#define SIGNAL_FLAG_QUEUING_REQUIRED           (0x10000)
        // force signal queuing, i.e. fail instead of falling back to unqueued
        // signals, when queuing isn't possible
-#define SIGNAL_FLAG_SEND_TO_THREAD                     (0x40000)
+#define SIGNAL_FLAG_SEND_TO_THREAD                     (0x20000)
        // interpret the the given ID as a thread_id rather than a team_id 
(syscall
        // use only)
 

Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp
===================================================================
--- haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp      
2011-05-23 23:30:59 UTC (rev 41697)
+++ haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp      
2011-05-24 00:51:44 UTC (rev 41698)
@@ -42,7 +42,8 @@
 #endif
 
 
-#define BLOCKABLE_SIGNALS              (~(KILL_SIGNALS | 
SIGNAL_TO_MASK(SIGSTOP)))
+#define BLOCKABLE_SIGNALS              (~(KILL_SIGNALS | 
SIGNAL_TO_MASK(SIGSTOP) \
+                                                                       | 
SIGNAL_TO_MASK(SIGNAL_CONTINUE_THREAD)))
 #define STOP_SIGNALS \
        (SIGNAL_TO_MASK(SIGSTOP) | SIGNAL_TO_MASK(SIGTSTP) \
        | SIGNAL_TO_MASK(SIGTTIN) | SIGNAL_TO_MASK(SIGTTOU))
@@ -60,7 +61,7 @@
 static const struct {
        const char*     name;
        int32           priority;
-} kSignalInfos[SIGNAL_REALTIME_MAX + 1] = {
+} kSignalInfos[__MAX_SIGNO + 1] = {
        {"NONE",                        -1},
        {"HUP",                         0},
        {"INT",                         0},
@@ -101,14 +102,38 @@
        {"SIGRT5",                      4},
        {"SIGRT6",                      3},
        {"SIGRT7",                      2},
-       {"SIGRT8",                      1}
+       {"SIGRT8",                      1},
+       {"invalid 41",          0},
+       {"invalid 42",          0},
+       {"invalid 43",          0},
+       {"invalid 44",          0},
+       {"invalid 45",          0},
+       {"invalid 46",          0},
+       {"invalid 47",          0},
+       {"invalid 48",          0},
+       {"invalid 49",          0},
+       {"invalid 50",          0},
+       {"invalid 51",          0},
+       {"invalid 52",          0},
+       {"invalid 53",          0},
+       {"invalid 54",          0},
+       {"invalid 55",          0},
+       {"invalid 56",          0},
+       {"invalid 57",          0},
+       {"invalid 58",          0},
+       {"invalid 59",          0},
+       {"invalid 60",          0},
+       {"invalid 61",          0},
+       {"invalid 62",          0},
+       {"invalid 63",          0},
+       {"SIGNAL_CONTINUE_THREAD",      99}
 };
 
 
 static inline const char*
 signal_name(uint32 number)
 {
-       return number <= MAX_SIGNAL_NUMBER ? kSignalInfos[number].name : 
"invalid";
+       return number <= __MAX_SIGNO ? kSignalInfos[number].name : "invalid";
 }
 
 
@@ -907,7 +932,13 @@
                schedulerLocker.Unlock();
 
                // get the action for the signal
-               struct sigaction handler = 
team->SignalActionFor(signal->Number());
+               struct sigaction handler;
+               if (signal->Number() <= MAX_SIGNAL_NUMBER) {
+                       handler = team->SignalActionFor(signal->Number());
+               } else {
+                       handler.sa_handler = SIG_DFL;
+                       handler.sa_flags = 0;
+               }
 
                if ((handler.sa_flags & SA_ONESHOT) != 0
                        && handler.sa_handler != SIG_IGN && handler.sa_handler 
!= SIG_DFL) {
@@ -958,6 +989,12 @@
                                                notify_debugger(thread, signal, 
handler, false);
                                        continue;
 
+                               case SIGNAL_CONTINUE_THREAD:
+                                       // prevent syscall restart, but 
otherwise ignore
+                                       restart = false;
+                                       atomic_and(&thread->flags, 
~THREAD_FLAGS_RESTART_SYSCALL);
+                                       continue;
+
                                case SIGCONT:
                                        // notify the debugger
                                        if (debugSignal
@@ -1225,9 +1262,6 @@
        \param flags A bitwise combination of any number of the following:
                - \c B_CHECK_PERMISSION: Check the caller's permission to send 
the
                        target thread the signal.
-               - \c SIGNAL_FLAG_DONT_RESTART_SYSCALL: If the signal interrupts 
the
-                       thread while waiting in a syscall, the syscall shall 
not be
-                       restarted automatically, but fail with \c B_INTERRUPTED 
instead.
        \return \c B_OK, when the signal was delivered successfully, another 
error
                code otherwise.
 */
@@ -1288,6 +1322,14 @@
                                thread_interrupt(thread, true);
                        break;
 
+               case SIGNAL_CONTINUE_THREAD:
+                       // wake up thread, and interrupt its current syscall
+                       if (thread->state == B_THREAD_SUSPENDED)
+                               scheduler_enqueue_in_run_queue(thread);
+
+                       atomic_or(&thread->flags, 
THREAD_FLAGS_DONT_RESTART_SYSCALL);
+                       break;
+
                case SIGCONT:
                        // Wake up thread if it was suspended, otherwise 
interrupt it, if
                        // the signal isn't blocked.
@@ -1296,9 +1338,6 @@
                        else if ((SIGNAL_TO_MASK(SIGCONT) & 
~thread->sig_block_mask) != 0)
                                thread_interrupt(thread, false);
 
-                       if ((flags & SIGNAL_FLAG_DONT_RESTART_SYSCALL) != 0)
-                               atomic_or(&thread->flags, 
THREAD_FLAGS_DONT_RESTART_SYSCALL);
-
                        // remove any pending stop signals
                        thread->RemovePendingSignals(STOP_SIGNALS);
                        break;
@@ -1332,9 +1371,6 @@
        \param flags A bitwise combination of any number of the following:
                - \c B_CHECK_PERMISSION: Check the caller's permission to send 
the
                        target thread the signal.
-               - \c SIGNAL_FLAG_DONT_RESTART_SYSCALL: If the signal interrupts 
the
-                       thread while waiting in a syscall, the syscall shall 
not be
-                       restarted automatically, but fail with \c B_INTERRUPTED 
instead.
                - \c B_DO_NOT_RESCHEDULE: If clear and a higher level thread 
has been
                        woken up, the scheduler will be invoked. If set that 
will not be
                        done explicitly, but rescheduling can still happen, 
e.g. when the

Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp
===================================================================
--- haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp      
2011-05-23 23:30:59 UTC (rev 41697)
+++ haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp      
2011-05-24 00:51:44 UTC (rev 41698)
@@ -2862,11 +2862,12 @@
 
        Thread* currentThread = thread_get_current_thread();
 
-       Signal signal(SIGCONT, SI_USER, B_OK, currentThread->team->id);
-       return send_signal_to_thread(id, signal, 
SIGNAL_FLAG_DONT_RESTART_SYSCALL);
-               // This retains compatibility to BeOS which documents the
-               // combination of suspend_thread() and resume_thread() to
-               // interrupt threads waiting on semaphores.
+       // Using the kernel internal SIGNAL_CONTINUE_THREAD signal retains
+       // compatibility to BeOS which documents the combination of 
suspend_thread()
+       // and resume_thread() to interrupt threads waiting on semaphores.
+       Signal signal(SIGNAL_CONTINUE_THREAD, SI_USER, B_OK,
+               currentThread->team->id);
+       return send_signal_to_thread(id, signal, 0);
 }
 
 


Other related posts:

  • » [haiku-commits] r41698 - in haiku/branches/developer/bonefish/signals: headers/private/kernel headers/private/system src/system/kernel - ingo_weinhold