xref: /trunk/main/sal/osl/os2/signal.c (revision cdf0e10c)
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