xref: /AOO41X/main/sal/osl/os2/signal.c (revision 647f063d49501903f1667b75f5634541fc603283)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 
25 /* system headers */
26 #include "system.h"
27 
28 #include <osl/diagnose.h>
29 #include <osl/mutex.h>
30 #include <osl/signal.h>
31 
32 typedef struct _oslSignalHandlerImpl
33 {
34     oslSignalHandlerFunction      Handler;
35     void*                         pData;
36     struct _oslSignalHandlerImpl* pNext;
37 } oslSignalHandlerImpl;
38 
39 static sal_Bool               bErrorReportingEnabled = sal_True;
40 static sal_Bool               bInitSignal = sal_False;
41 static oslMutex               SignalListMutex;
42 static oslSignalHandlerImpl*  SignalList;
43 
44 /*static*//* ULONG _Export APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
45                                             PEXCEPTIONREGISTRATIONRECORD,
46                                             PCONTEXTRECORD, PVOID);
47 */
48 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
49                                             PEXCEPTIONREGISTRATIONRECORD,
50                                             PCONTEXTRECORD, PVOID);
51 static EXCEPTIONREGISTRATIONRECORD ExcptHandler = { 0, SignalHandlerFunction };
52 
InitSignal(void)53 static sal_Bool InitSignal( void )
54 {
55     SignalListMutex = osl_createMutex();
56 
57     ExcptHandler.ExceptionHandler = (_ERR *) &SignalHandlerFunction;
58     /* DosSetExceptionHandler(&ExcptHandler); */
59 
60     return sal_True;
61 }
62 
DeInitSignal(void)63 static sal_Bool DeInitSignal( void )
64 {
65     /* DosUnsetExceptionHandler(&ExcptHandler); */
66 
67     osl_destroyMutex(SignalListMutex);
68 
69     return sal_False;
70 }
71 
CallSignalHandler(oslSignalInfo * pInfo)72 static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
73 {
74     oslSignalHandlerImpl* pHandler = SignalList;
75     oslSignalAction Action = osl_Signal_ActCallNextHdl;
76 
77     while (pHandler != NULL)
78     {
79         if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl)
80             break;
81 
82         pHandler = pHandler->pNext;
83     }
84 
85     return Action;
86 }
87 
88 /*****************************************************************************/
89 /* SignalHandlerFunction    */
90 /*****************************************************************************/
SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,PEXCEPTIONREGISTRATIONRECORD pERegRec,PCONTEXTRECORD pConRec,PVOID pReserved)91 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
92                                             PEXCEPTIONREGISTRATIONRECORD pERegRec,
93                                             PCONTEXTRECORD pConRec, PVOID pReserved)
94 {
95     oslSignalInfo    Info;
96 
97     Info.UserSignal = pERepRec->ExceptionNum;
98     Info.UserData   = NULL;
99 
100     switch (pERepRec->ExceptionNum)
101     {
102         case XCPT_ACCESS_VIOLATION:
103             Info.Signal = osl_Signal_AccessViolation;
104             break;
105 
106         case XCPT_INTEGER_DIVIDE_BY_ZERO:
107             Info.Signal = osl_Signal_IntegerDivideByZero;
108             break;
109 
110         case XCPT_BREAKPOINT:
111             Info.Signal = osl_Signal_DebugBreak;
112             break;
113 
114         default:
115             Info.Signal = osl_Signal_System;
116             break;
117     }
118 
119     switch (CallSignalHandler(&Info))
120     {
121         case osl_Signal_ActCallNextHdl:
122             return (XCPT_CONTINUE_SEARCH);
123 
124         case osl_Signal_ActAbortApp:
125             return (XCPT_CONTINUE_SEARCH);
126 
127         case osl_Signal_ActKillApp:
128             exit(255);
129             break;
130     }
131 
132     return (XCPT_CONTINUE_SEARCH);
133 }
134 
135 /*****************************************************************************/
136 /* osl_addSignalHandler */
137 /*****************************************************************************/
osl_addSignalHandler(oslSignalHandlerFunction Handler,void * pData)138 oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
139 {
140     oslSignalHandlerImpl* pHandler;
141 
142     OSL_ASSERT(Handler != NULL);
143 
144     if (! bInitSignal)
145         bInitSignal = InitSignal();
146 
147     pHandler = (oslSignalHandlerImpl*) calloc(1, sizeof(oslSignalHandlerImpl));
148 
149     if (pHandler != NULL)
150     {
151         pHandler->Handler = Handler;
152         pHandler->pData   = pData;
153 
154         osl_acquireMutex(SignalListMutex);
155 
156         pHandler->pNext = SignalList;
157         SignalList      = pHandler;
158 
159         osl_releaseMutex(SignalListMutex);
160 
161         return (pHandler);
162     }
163 
164     return (NULL);
165 }
166 
167 /*****************************************************************************/
168 /* osl_removeSignalHandler */
169 /*****************************************************************************/
osl_removeSignalHandler(oslSignalHandler Handler)170 sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
171 {
172     oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
173 
174     OSL_ASSERT(Handler != NULL);
175 
176     if (! bInitSignal)
177         bInitSignal = InitSignal();
178 
179     osl_acquireMutex(SignalListMutex);
180 
181     pHandler = SignalList;
182 
183     while (pHandler != NULL)
184     {
185         if (pHandler == Handler)
186         {
187             if (pPrevious)
188                 pPrevious->pNext = pHandler->pNext;
189             else
190                 SignalList = pHandler->pNext;
191 
192             osl_releaseMutex(SignalListMutex);
193 
194             if (SignalList == NULL )
195                 bInitSignal = DeInitSignal();
196 
197             free(pHandler);
198 
199             return (sal_True);
200         }
201 
202         pPrevious = pHandler;
203         pHandler  = pHandler->pNext;
204     }
205 
206     osl_releaseMutex(SignalListMutex);
207 
208     return (sal_False);
209 }
210 
211 /*****************************************************************************/
212 /* osl_raiseSignal */
213 /*****************************************************************************/
osl_raiseSignal(sal_Int32 UserSignal,void * UserData)214 oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
215 {
216     oslSignalInfo   Info;
217     oslSignalAction Action;
218 
219     if (! bInitSignal)
220         bInitSignal = InitSignal();
221 
222     osl_acquireMutex(SignalListMutex);
223 
224     Info.Signal     = osl_Signal_User;
225     Info.UserSignal = UserSignal;
226     Info.UserData   = UserData;
227 
228     Action = CallSignalHandler(&Info);
229 
230     osl_releaseMutex(SignalListMutex);
231 
232     return (Action);
233 }
234 
235 /*****************************************************************************/
236 /* osl_setErrorReporting */
237 /*****************************************************************************/
osl_setErrorReporting(sal_Bool bEnable)238 sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
239 {
240     sal_Bool bOld = bErrorReportingEnabled;
241     bErrorReportingEnabled = bEnable;
242 
243     return bOld;
244 }
245 
246