This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos 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]

Fix to timer signal delivery



Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/compat/posix/current/ChangeLog,v
retrieving revision 1.34
diff -u -5 -r1.34 ChangeLog
--- ChangeLog	20 Jan 2003 13:09:20 -0000	1.34
+++ ChangeLog	31 Jan 2003 11:50:47 -0000
@@ -1,5 +1,22 @@
+2003-01-31  Nick Garnett  <nickg@calivar.com>
+
+	* src/time.cxx (alarm_action): Added call to
+	cyg_posix_signal_sigwait() to wake up any sigwait()ing threads.
+
+	* src/signal.cxx (cyg_posix_signal_sigwait): Added this function
+	to export access to signal_sigwait conditional variable.
+	(sigtimedwait): Added call to cyg_posix_timer_asr() to allow timer
+	signals to be delivered here.
+
+	* src/pprivate.h: Added prototype for cyg_posix_signal_sigwait().
+
+	* cdl/posix.cdl:
+	* tests/signal3.c: Added this program to test interaction of
+	timers and signals, particularly sigwait(). Based on a test
+	program from N.Suresh <nsuresh@cdotb.ernet.in>.
+
 2003-01-20  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* src/signal.cxx (cyg_posix_deliver_signals): silence warning.
 
 	* src/time.cxx (cyg_timespec_to_ticks): Remove use of default arg in
Index: cdl/posix.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/compat/posix/current/cdl/posix.cdl,v
retrieving revision 1.9
diff -u -5 -r1.9 posix.cdl
--- cdl/posix.cdl	23 May 2002 22:59:55 -0000	1.9
+++ cdl/posix.cdl	31 Jan 2003 11:50:48 -0000
@@ -300,11 +300,11 @@
             display "POSIX tests"
             flavor  data
             no_define
             calculated { 
                 "tests/pthread1 tests/pthread2 tests/pthread3 tests/mutex3 tests/mqueue2"
-                . ((CYGPKG_POSIX_SIGNALS) ? " tests/mqueue1 tests/signal1 tests/signal2 tests/sigsetjmp tests/timer1 tests/tm_basic" : "")
+                . ((CYGPKG_POSIX_SIGNALS) ? " tests/mqueue1 tests/signal1 tests/signal2 tests/signal3 tests/sigsetjmp tests/timer1 tests/tm_basic" : "")
             }
             description   "
                 This option specifies the set of tests for the POSIX package."
         }
 
Index: src/pprivate.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/compat/posix/current/src/pprivate.h,v
retrieving revision 1.7
diff -u -5 -r1.7 pprivate.h
--- src/pprivate.h	23 May 2002 22:59:59 -0000	1.7
+++ src/pprivate.h	31 Jan 2003 11:50:48 -0000
@@ -225,11 +225,13 @@
 
 externC cyg_bool cyg_sigqueue( const struct sigevent *sev, int code,
                                pthread_info *thread = NULL );
 
 externC cyg_bool cyg_deliver_signals();
-    
+
+externC void cyg_posix_signal_sigwait();
+
 externC void cyg_posix_thread_siginit( pthread_info *thread,
                                        pthread_info *parentthread );
 
 externC void cyg_posix_thread_sigdestroy( pthread_info *thread );
 #endif
Index: src/signal.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/compat/posix/current/src/signal.cxx,v
retrieving revision 1.16
diff -u -5 -r1.16 signal.cxx
--- src/signal.cxx	20 Jan 2003 19:32:09 -0000	1.16
+++ src/signal.cxx	31 Jan 2003 11:50:54 -0000
@@ -433,10 +433,18 @@
     
     return res;
 }
 
 // -------------------------------------------------------------------------
+// Utility routine to signal any threads waiting in sigwait*().
+
+void cyg_posix_signal_sigwait()
+{
+    signal_sigwait.broadcast();
+}       
+
+// -------------------------------------------------------------------------
 // Action routine called from kernel alarm to deliver the SIGALRM signal.
 // We cannot call any signal delivery functions directly here, so we simply
 // set a flag and schedule an ASR to be called.
 
 static void sigalrm_action( Cyg_Alarm *alarm, CYG_ADDRWORD data )
@@ -916,10 +924,12 @@
         }
         
         // Special case check for SIGALRM since the fact SIGALRM is masked
         // would have prevented it being set pending in the alarm handler.
         check_sigalarm();
+
+        cyg_posix_timer_asr(self);
     }
 
     if( err == 0 )
     {
         // There is a signal in the set that is pending: deliver
Index: src/time.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/compat/posix/current/src/time.cxx,v
retrieving revision 1.8
diff -u -5 -r1.8 time.cxx
--- src/time.cxx	20 Jan 2003 13:09:20 -0000	1.8
+++ src/time.cxx	31 Jan 2003 11:50:54 -0000
@@ -270,10 +270,11 @@
             timer->pending = true;
     
             sigset_t mask;
             sigemptyset( &mask );
             sigaddset( &mask, timer->sigev.sigev_signo );
+            cyg_posix_signal_sigwait();
             cyg_posix_pthread_release_thread( &mask );
         }
         else if( timer->sigev.sigev_notify == SIGEV_THREAD )
         {
             // Thread style notification
Index: tests/signal1.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/compat/posix/current/tests/signal1.c,v
retrieving revision 1.5
diff -u -5 -r1.5 signal1.c
--- tests/signal1.c	23 May 2002 23:00:02 -0000	1.5
+++ tests/signal1.c	31 Jan 2003 11:50:54 -0000
@@ -181,11 +181,11 @@
 
     // Set signal mask
     pthread_sigmask( SIG_SETMASK, &mask, NULL );
     
     alarm(1);
-    CYG_TEST_INFO( "Thread1: calling alarm()");            
+    CYG_TEST_INFO( "Thread1: calling sigwait()");            
     err = sigwait( &mask, &sig);
     CYG_TEST_CHECK( 0==err, "sigwait returned -1");
     CYG_TEST_CHECK( sig==SIGALRM, "sigwait caught alarm");
 
     CYG_TEST_INFO( "Thread1: calling pthread_exit()");    
Index: tests/signal3.c
===================================================================
RCS file: tests/signal3.c
diff -N tests/signal3.c
--- tests/signal3.c	1 Jan 1970 00:00:00 -0000
+++ tests/signal3.c	31 Jan 2003 11:50:54 -0000
@@ -0,0 +1,174 @@
+//==========================================================================
+//
+//        signal3.cxx
+//
+//        POSIX signal test 3
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2003-01-30
+// Description:   Tests POSIX signal functionality.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#if !defined(CYGPKG_POSIX_SIGNALS)
+#define NA_MSG "POSIX signals not enabled"
+#elif !defined(CYGPKG_POSIX_PTHREAD)
+#define NA_MSG "POSIX threads not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <signal.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include <cyg/infra/diag.h>
+
+volatile int sigusr1_called = 0;
+
+//--------------------------------------------------------------------------
+// Signal handler functions
+
+static void sigusr1( int signo )
+{
+    CYG_TEST_INFO( "sigusr1() handler called" );
+    CYG_TEST_CHECK( signo == SIGUSR1, "Signal not SIGUSR1");
+
+    sigusr1_called++;
+}
+
+//--------------------------------------------------------------------------
+
+int main (int argc, char **argv)
+{
+    int ret_val;
+    sigset_t set;
+    int sig;
+
+    CYG_TEST_INIT();
+
+    {
+        struct sigaction sa;
+
+        sa.sa_handler = sigusr1;
+        sigfillset( &sa.sa_mask );
+        sa.sa_flags = 0;
+
+        ret_val = sigaction( SIGUSR1, &sa, NULL );
+
+        CYG_TEST_CHECK( ret_val == 0 , "sigaction returned error");
+    }
+    
+    // unblock all the signals
+    sigfillset (&set);
+    pthread_sigmask (SIG_UNBLOCK, &set, (sigset_t*)NULL);
+    
+    //--------------------------------------------------------------------
+    // <start of timer initialization section>
+    //--------------------------------------------------------------------
+    struct itimerspec timerValue;	// Timeout value on eCos
+    timer_t timer1;			// Timer
+    struct sigevent sev;
+	
+    // Notification type --- Deliver the signal
+    sev.sigev_notify                = SIGEV_SIGNAL;
+    sev.sigev_signo                 = SIGUSR1;
+    sev.sigev_value.sival_int       = 0xABCDEF01;
+	
+    // Timer values	--- 1 Second
+    timerValue.it_value.tv_sec           = 1;
+    timerValue.it_value.tv_nsec          = 0;
+    timerValue.it_interval.tv_sec        = 1;
+    timerValue.it_interval.tv_nsec       = 0;
+	
+    ret_val = timer_create (CLOCK_REALTIME, &sev, &timer1);
+
+    CYG_TEST_CHECK( ret_val==0, "Error in creating the timer");
+
+    ret_val = timer_settime (timer1, 0, &timerValue, NULL );
+    CYG_TEST_CHECK( ret_val==0,"Error in setting the time");
+
+    //--------------------------------------------------------------------
+    // <end of timer initialization section>
+    //--------------------------------------------------------------------
+
+    CYG_TEST_INFO ("Timer initialisation is completed..");
+
+    CYG_TEST_INFO ("Calling pause()");
+    ret_val = pause();
+    CYG_TEST_CHECK( ret_val==-1, "pause() did not return -1");
+    CYG_TEST_CHECK( EINTR==errno, "errno set to EINTR");
+    CYG_TEST_CHECK( sigusr1_called==1, "Siguser1 handler not called");
+    
+    // Block all the signals
+    sigfillset (&set);
+    pthread_sigmask (SIG_BLOCK, &set, (sigset_t*)NULL);
+
+    CYG_TEST_INFO ("Calling sigwait()");    
+    // Wait for any signal to arrive
+    sigfillset (&set);
+    ret_val = sigwait (&set, &sig);
+
+    CYG_TEST_CHECK( ret_val==0, "sigwait returned error");
+    CYG_TEST_CHECK( sig==SIGUSR1, "sigwait returned wrong signo!");
+    CYG_TEST_CHECK( sigusr1_called==1, "Siguser1 handler called!");
+    
+    CYG_TEST_INFO ("Program terminating");
+
+    CYG_TEST_PASS_FINISH( "signal3" );
+    return 0;
+}
+
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of signal3.c


-- 
Nick Garnett - eCos Kernel Architect
http://www.eCosCentric.com/


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