File indexing completed on 2025-05-11 08:24:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040
0041 #include <errno.h>
0042 #include <pthread.h>
0043 #include <signal.h>
0044
0045 #include <rtems/score/isr.h>
0046 #include <rtems/score/threadimpl.h>
0047 #include <rtems/score/threadqimpl.h>
0048 #include <rtems/score/watchdogimpl.h>
0049 #include <rtems/posix/threadsup.h>
0050 #include <rtems/posix/psignalimpl.h>
0051 #include <rtems/posix/pthreadimpl.h>
0052 #include <stdio.h>
0053
0054 static void _POSIX_signals_Check_signal(
0055 POSIX_API_Control *api,
0056 int signo,
0057 bool is_global
0058 )
0059 {
0060 siginfo_t siginfo_struct;
0061 sigset_t saved_signals_unblocked;
0062
0063 if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct,
0064 is_global, true, true ) )
0065 return;
0066
0067
0068
0069
0070
0071 #if defined(RTEMS_DEBUG)
0072 assert( _POSIX_signals_Vectors[ signo ].sa_handler ||
0073 _POSIX_signals_Vectors[ signo ].sa_sigaction );
0074 #endif
0075
0076
0077
0078
0079 if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN )
0080 return;
0081
0082
0083
0084
0085 saved_signals_unblocked = api->signals_unblocked;
0086 api->signals_unblocked &= ~_POSIX_signals_Vectors[ signo ].sa_mask;
0087
0088
0089
0090
0091 switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
0092 case SA_SIGINFO:
0093 (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
0094 signo,
0095 &siginfo_struct,
0096 NULL
0097 );
0098 break;
0099 default:
0100 (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
0101 break;
0102 }
0103
0104
0105
0106
0107 api->signals_unblocked = saved_signals_unblocked;
0108 }
0109
0110 static void _POSIX_signals_Action_handler(
0111 Thread_Control *executing,
0112 Thread_Action *action,
0113 ISR_lock_Context *lock_context
0114 )
0115 {
0116 POSIX_API_Control *api;
0117 int signo;
0118 uint32_t hold_errno;
0119
0120 (void) action;
0121 _Thread_State_release( executing, lock_context );
0122
0123 api = executing->API_Extensions[ THREAD_API_POSIX ];
0124
0125
0126
0127
0128
0129 hold_errno = executing->Wait.return_code;
0130
0131
0132
0133
0134
0135 _Assert(
0136 ( _Thread_Wait_flags_get( executing )
0137 & ( THREAD_WAIT_STATE_BLOCKED | THREAD_WAIT_STATE_INTEND_TO_BLOCK ) ) == 0
0138 );
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 while (1) {
0149 Thread_queue_Context queue_context;
0150
0151 _Thread_queue_Context_initialize( &queue_context );
0152 _POSIX_signals_Acquire( &queue_context );
0153 if ( !(api->signals_unblocked &
0154 (api->signals_pending | _POSIX_signals_Pending)) ) {
0155 _POSIX_signals_Release( &queue_context );
0156 break;
0157 }
0158 _POSIX_signals_Release( &queue_context );
0159
0160 for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
0161 _POSIX_signals_Check_signal( api, signo, false );
0162 _POSIX_signals_Check_signal( api, signo, true );
0163 }
0164
0165
0166 for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
0167 _POSIX_signals_Check_signal( api, signo, false );
0168 _POSIX_signals_Check_signal( api, signo, true );
0169 }
0170 }
0171
0172 executing->Wait.return_code = hold_errno;
0173
0174 _Thread_State_acquire( executing, lock_context );
0175 }
0176
0177 static bool _POSIX_signals_Unblock_thread_done(
0178 Thread_Control *the_thread,
0179 POSIX_API_Control *api,
0180 bool status
0181 )
0182 {
0183 ISR_lock_Context lock_context;
0184
0185 _Thread_State_acquire( the_thread, &lock_context );
0186 _Thread_Add_post_switch_action(
0187 the_thread,
0188 &api->Signal_action,
0189 _POSIX_signals_Action_handler
0190 );
0191 _Thread_State_release( the_thread, &lock_context );
0192
0193 return status;
0194 }
0195
0196 bool _POSIX_signals_Unblock_thread(
0197 Thread_Control *the_thread,
0198 int signo,
0199 siginfo_t *info
0200 )
0201 {
0202 POSIX_API_Control *api;
0203 sigset_t mask;
0204 siginfo_t *the_info = NULL;
0205
0206 api = the_thread->API_Extensions[ THREAD_API_POSIX ];
0207
0208 mask = signo_to_mask( signo );
0209
0210
0211
0212
0213
0214 if ( _States_Is_interruptible_signal( the_thread->current_state ) ) {
0215
0216 if ( (the_thread->Wait.option & mask) || (api->signals_unblocked & mask) ) {
0217 the_info = (siginfo_t *) the_thread->Wait.return_argument;
0218
0219 if ( !info ) {
0220 the_info->si_signo = signo;
0221 the_info->si_code = SI_USER;
0222 the_info->si_value.sival_int = 0;
0223 } else {
0224 *the_info = *info;
0225 }
0226
0227 _Thread_Timer_remove_and_continue( the_thread, STATUS_INTERRUPTED );
0228 return _POSIX_signals_Unblock_thread_done( the_thread, api, true );
0229 }
0230
0231
0232
0233
0234
0235 return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
0236 }
0237
0238
0239
0240
0241 if ( api->signals_unblocked & mask ) {
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 if ( _States_Is_interruptible_by_signal( the_thread->current_state ) ) {
0257 _Thread_Timer_remove_and_continue( the_thread, STATUS_INTERRUPTED );
0258 }
0259 }
0260 return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
0261 }