xref: /trunk/main/sal/osl/os2/signal.c (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 /* system headers */
30 #include "system.h"
31 
32 #include <osl/diagnose.h>
33 #include <osl/mutex.h>
34 #include <osl/signal.h>
35 
36 typedef struct _oslSignalHandlerImpl
37 {
38     oslSignalHandlerFunction      Handler;
39     void*                         pData;
40     struct _oslSignalHandlerImpl* pNext;
41 } oslSignalHandlerImpl;
42 
43 static sal_Bool               bErrorReportingEnabled = sal_True;
44 static sal_Bool               bInitSignal = sal_False;
45 static oslMutex               SignalListMutex;
46 static oslSignalHandlerImpl*  SignalList;
47 
48 /*static*//* ULONG _Export APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
49                                             PEXCEPTIONREGISTRATIONRECORD,
50                                             PCONTEXTRECORD, PVOID);
51 */
52 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
53                                             PEXCEPTIONREGISTRATIONRECORD,
54                                             PCONTEXTRECORD, PVOID);
55 static EXCEPTIONREGISTRATIONRECORD ExcptHandler = { 0, SignalHandlerFunction };
56 
57 static sal_Bool InitSignal( void )
58 {
59     SignalListMutex = osl_createMutex();
60 
61     ExcptHandler.ExceptionHandler = (_ERR *) &SignalHandlerFunction;
62     /* DosSetExceptionHandler(&ExcptHandler); */
63 
64     return sal_True;
65 }
66 
67 static sal_Bool DeInitSignal( void )
68 {
69     /* DosUnsetExceptionHandler(&ExcptHandler); */
70 
71     osl_destroyMutex(SignalListMutex);
72 
73     return sal_False;
74 }
75 
76 static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
77 {
78     oslSignalHandlerImpl* pHandler = SignalList;
79     oslSignalAction Action = osl_Signal_ActCallNextHdl;
80 
81     while (pHandler != NULL)
82     {
83         if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl)
84             break;
85 
86         pHandler = pHandler->pNext;
87     }
88 
89     return Action;
90 }
91 
92 /*****************************************************************************/
93 /* SignalHandlerFunction    */
94 /*****************************************************************************/
95 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
96                                             PEXCEPTIONREGISTRATIONRECORD pERegRec,
97                                             PCONTEXTRECORD pConRec, PVOID pReserved)
98 {
99     oslSignalInfo    Info;
100 
101     Info.UserSignal = pERepRec->ExceptionNum;
102     Info.UserData   = NULL;
103 
104     switch (pERepRec->ExceptionNum)
105     {
106         case XCPT_ACCESS_VIOLATION:
107             Info.Signal = osl_Signal_AccessViolation;
108             break;
109 
110         case XCPT_INTEGER_DIVIDE_BY_ZERO:
111             Info.Signal = osl_Signal_IntegerDivideByZero;
112             break;
113 
114         case XCPT_BREAKPOINT:
115             Info.Signal = osl_Signal_DebugBreak;
116             break;
117 
118         default:
119             Info.Signal = osl_Signal_System;
120             break;
121     }
122 
123     switch (CallSignalHandler(&Info))
124     {
125         case osl_Signal_ActCallNextHdl:
126             return (XCPT_CONTINUE_SEARCH);
127 
128         case osl_Signal_ActAbortApp:
129             return (XCPT_CONTINUE_SEARCH);
130 
131         case osl_Signal_ActKillApp:
132             exit(255);
133             break;
134     }
135 
136     return (XCPT_CONTINUE_SEARCH);
137 }
138 
139 /*****************************************************************************/
140 /* osl_addSignalHandler */
141 /*****************************************************************************/
142 oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
143 {
144     oslSignalHandlerImpl* pHandler;
145 
146     OSL_ASSERT(Handler != NULL);
147 
148     if (! bInitSignal)
149         bInitSignal = InitSignal();
150 
151     pHandler = (oslSignalHandlerImpl*) calloc(1, sizeof(oslSignalHandlerImpl));
152 
153     if (pHandler != NULL)
154     {
155         pHandler->Handler = Handler;
156         pHandler->pData   = pData;
157 
158         osl_acquireMutex(SignalListMutex);
159 
160         pHandler->pNext = SignalList;
161         SignalList      = pHandler;
162 
163         osl_releaseMutex(SignalListMutex);
164 
165         return (pHandler);
166     }
167 
168     return (NULL);
169 }
170 
171 /*****************************************************************************/
172 /* osl_removeSignalHandler */
173 /*****************************************************************************/
174 sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
175 {
176     oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
177 
178     OSL_ASSERT(Handler != NULL);
179 
180     if (! bInitSignal)
181         bInitSignal = InitSignal();
182 
183     osl_acquireMutex(SignalListMutex);
184 
185     pHandler = SignalList;
186 
187     while (pHandler != NULL)
188     {
189         if (pHandler == Handler)
190         {
191             if (pPrevious)
192                 pPrevious->pNext = pHandler->pNext;
193             else
194                 SignalList = pHandler->pNext;
195 
196             osl_releaseMutex(SignalListMutex);
197 
198             if (SignalList == NULL )
199                 bInitSignal = DeInitSignal();
200 
201             free(pHandler);
202 
203             return (sal_True);
204         }
205 
206         pPrevious = pHandler;
207         pHandler  = pHandler->pNext;
208     }
209 
210     osl_releaseMutex(SignalListMutex);
211 
212     return (sal_False);
213 }
214 
215 /*****************************************************************************/
216 /* osl_raiseSignal */
217 /*****************************************************************************/
218 oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
219 {
220     oslSignalInfo   Info;
221     oslSignalAction Action;
222 
223     if (! bInitSignal)
224         bInitSignal = InitSignal();
225 
226     osl_acquireMutex(SignalListMutex);
227 
228     Info.Signal     = osl_Signal_User;
229     Info.UserSignal = UserSignal;
230     Info.UserData   = UserData;
231 
232     Action = CallSignalHandler(&Info);
233 
234     osl_releaseMutex(SignalListMutex);
235 
236     return (Action);
237 }
238 
239 /*****************************************************************************/
240 /* osl_setErrorReporting */
241 /*****************************************************************************/
242 sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
243 {
244     sal_Bool bOld = bErrorReportingEnabled;
245     bErrorReportingEnabled = bEnable;
246 
247     return bOld;
248 }
249 
250