1 /* # skkinput (Simple Kana-Kanji Input)
2  *
3  * This file is part of skkinput.
4  * Copyright (C) 2002
5  * Takashi SAKAMOTO (PXG01715@nifty.ne.jp)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with skkinput; see the file COPYING.  If not, write to
19  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 #include "local.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include "lispmgrp.h"
27 
28 static	Boolean	lispMgr_registerNoNameMutex	(TLispManager*, TLispEntity*) ;
29 static	Boolean	lispMgr_registerNamedMutex	(TLispManager*, TLispEntity*) ;
30 static	void	lispMgr_abondonMutexSub		(TLispManager*, TLispEntity*, const void*) ;
31 
32 Boolean
lispMgr_CreateMutex(register TLispManager * pLispMgr,register const Char * pMutexName,register int nMutexName,register TLispEntity ** const ppEntReturn)33 lispMgr_CreateMutex (
34 	register TLispManager* 			pLispMgr,
35 	register const Char*			pMutexName,
36 	register int					nMutexName,
37 	register TLispEntity** const	ppEntReturn)
38 {
39 	TLispEntity*	pEntity ;
40 	register TLispMutex*	pMutex ;
41 	register size_t			nSize ;
42 
43 	assert (pLispMgr    != NULL) ;
44 	assert (pMutexName  != NULL || nMutexName == 0) ;
45 	assert (ppEntReturn != NULL) ;
46 
47 #if defined (DEBUG_LV99)
48 	fprintf (stderr, "Garbage collecting ...") ;
49 	fflush (stderr) ;
50 	lispMgr_CollectGarbage (pLispMgr) ;
51 	fprintf (stderr, "done.\n") ;
52 #endif
53 	nSize	= sizeof (TLispMutex) + sizeof (Char) * ((nMutexName > 1)? nMutexName - 1 : 0) ;
54 	if (TFAILED (lispMgr_AllocateEntity (pLispMgr, nSize, &pEntity)))
55 		return	False ;
56 
57 	pEntity->m_iType		= LISPENTITY_MUTEX ;
58 	pEntity->m_lReferCount	= (nMutexName > 0)? 1 : 0 ;
59 
60 	pMutex					= lispEntity_GetMutexPtr (pEntity) ;
61 	pMutex->m_nLength		= nMutexName ;
62 	if (nMutexName > 0)
63 		memcpy (pMutex->m_achString, pMutexName, sizeof (Char) * nMutexName) ;
64 	pMutex->m_uLockCount	= 0 ;
65 	pMutex->m_pOwner		= NULL ;
66 
67 	if (nMutexName > 0) {
68 		lispMgr_registerNamedMutex  (pLispMgr, pEntity) ;
69 	} else {
70 		lispMgr_registerNoNameMutex (pLispMgr, pEntity) ;
71 	}
72 	*ppEntReturn	= pEntity ;
73 	return	True ;
74 }
75 
76 Boolean
lispEntity_Mutexp(register TLispManager * pLispMgr,register TLispEntity * pEntMutex)77 lispEntity_Mutexp (
78 	register TLispManager*	pLispMgr,
79 	register TLispEntity*	pEntMutex)
80 {
81 	assert (pLispMgr  != NULL) ;
82 	assert (pEntMutex != NULL) ;
83 	return	(pEntMutex->m_iType == LISPENTITY_MUTEX) ;
84 }
85 
86 Boolean
lispMgr_LockMutex(register TLispManager * pLispMgr,register TLispEntity * pEntMutex,register void * pOwner)87 lispMgr_LockMutex (
88 	register TLispManager*	pLispMgr,
89 	register TLispEntity*	pEntMutex,
90 	register void*			pOwner)
91 {
92 	register TLispMutex*	pMutex ;
93 
94 	assert (pLispMgr  != NULL) ;
95 	assert (pEntMutex != NULL) ;
96 	assert (pOwner    != NULL) ;
97 
98 	pMutex	= lispEntity_GetMutexPtr (pEntMutex) ;
99 	if (pMutex->m_uLockCount > 0 && pMutex->m_pOwner != pOwner)
100 		return	False ;
101 
102 	/*	��å��Ǥ���³���Ķ����ȥ��顼��*/
103 	if (pMutex->m_uLockCount == (unsigned int)-1)
104 		return	False ;
105 
106 	pMutex->m_uLockCount	++ ;
107 	pMutex->m_pOwner	= pOwner ;
108 	return	True ;
109 }
110 
111 Boolean
lispMgr_UnlockMutex(register TLispManager * pLispMgr,register TLispEntity * pEntMutex,register void * pOwner)112 lispMgr_UnlockMutex (
113 	register TLispManager*	pLispMgr,
114 	register TLispEntity*	pEntMutex,
115 	register void*			pOwner)
116 {
117 	register TLispMutex*	pMutex ;
118 
119 	assert (pLispMgr  != NULL) ;
120 	assert (pEntMutex != NULL) ;
121 	assert (pOwner    != NULL) ;
122 
123 	pMutex	= lispEntity_GetMutexPtr (pEntMutex) ;
124 	if (pMutex->m_uLockCount == 0 || pMutex->m_pOwner != pOwner)
125 		return	False ;
126 
127 	pMutex->m_uLockCount	-- ;
128 	if (pMutex->m_uLockCount == 0)
129 		pMutex->m_pOwner	= NULL ;
130 	return	True ;
131 }
132 
133 Boolean
lispEntity_GetMutexInfo(register TLispManager * pLispMgr,register TLispEntity * pEntMutex,register const Char ** ppString,register int * pnString,register unsigned int * puLockCount,register const void ** ppOwner)134 lispEntity_GetMutexInfo (
135 	register TLispManager*	pLispMgr,
136 	register TLispEntity*	pEntMutex,
137 	register const Char**	ppString,
138 	register int*			pnString,
139 	register unsigned int*	puLockCount,
140 	register const void**	ppOwner)
141 {
142 	register TLispMutex*	pMutex ;
143 
144 	assert (pLispMgr  != NULL) ;
145 	assert (pEntMutex != NULL) ;
146 
147 	if (pEntMutex->m_iType != LISPENTITY_MUTEX)
148 		return	False ;
149 
150 	pMutex		= lispEntity_GetMutexPtr (pEntMutex) ;
151 	if (ppString != NULL)
152 		*ppString	= pMutex->m_achString ;
153 	if (pnString != NULL)
154 		*pnString	= pMutex->m_nLength ;
155 	if (puLockCount != NULL)
156 		*puLockCount	= pMutex->m_uLockCount ;
157 	if (ppOwner != NULL)
158 		*ppOwner	= pMutex->m_pOwner ;
159 	return	True ;
160 }
161 
162 Boolean
lispMgr_SearchMutex(register TLispManager * pLispMgr,register const Char * pMutexName,register int nMutexName,register TLispEntity ** const ppEntReturn)163 lispMgr_SearchMutex (
164 	register TLispManager*			pLispMgr,
165 	register const Char*			pMutexName,
166 	register int					nMutexName,
167 	register TLispEntity**	const	ppEntReturn)
168 {
169 	register TLispEntity*	pNode ;
170 	register TLispMutex*	pNodeMutex ;
171 	register const Char*	pNodeMutexName ;
172 	register int			nNodeMutexName ;
173 
174 	assert (pLispMgr    != NULL) ;
175 	assert (ppEntReturn != NULL) ;
176 
177 	if (pMutexName == NULL || nMutexName <= 0)
178 		return	False ;
179 
180 	pNode		= pLispMgr->m_pEntListNamedMutex ;
181 	while (pNode != NULL) {
182 		pNodeMutex		= lispEntity_GetMutexPtr (pNode) ;
183 		pNodeMutexName	= pNodeMutex->m_achString ;
184 		nNodeMutexName	= pNodeMutex->m_nLength ;
185 		/*	�������¤�Ǥ����ΤȤ��Ƥ��롣*/
186 		if (nNodeMutexName == nMutexName &&
187 			!Cstrncmp (pMutexName, pNodeMutexName, nMutexName)) {
188 			*ppEntReturn	= pNode ;
189 			return	True ;
190 		}
191 		pNode			= pNode->m_pRight ;
192 	}
193 	return	False ;
194 }
195 
196 /*	Mutex �ζ���������
197  */
198 void
lispMgr_AbondonMutex(register TLispManager * pLispMgr,register const void * pOwner)199 lispMgr_AbondonMutex (
200 	register TLispManager*	pLispMgr,
201 	register const void*	pOwner)
202 {
203 	lispMgr_abondonMutexSub (pLispMgr, pLispMgr->m_pEntListNamedMutex, pOwner) ;
204 	lispMgr_abondonMutexSub (pLispMgr, pLispMgr->m_pEntListNoNameMutex, pOwner) ;
205 	return ;
206 }
207 
208 Boolean
lispMgr_registerNoNameMutex(register TLispManager * pLispMgr,register TLispEntity * pEntMutex)209 lispMgr_registerNoNameMutex (
210 	register TLispManager*	pLispMgr,
211 	register TLispEntity*	pEntMutex)
212 {
213 	register TLispEntity*	pNode ;
214 	register TLispMutex*	pMutex ;
215 	/*register const Char*	pMutexName ;*/
216 	register int			nMutexName ;
217 
218 	assert (pLispMgr != NULL) ;
219 	assert (pEntMutex  != NULL) ;
220 	assert (pEntMutex->m_iType == LISPENTITY_MUTEX) ;
221 
222 	pMutex		= lispEntity_GetMutexPtr (pEntMutex) ;
223 	nMutexName	= pMutex->m_nLength ;
224 	assert (nMutexName == 0) ;
225 
226 	pNode				= pLispMgr->m_pEntListNoNameMutex ;
227 	pEntMutex->m_pRight	= pNode ;
228 	pEntMutex->m_pLeft	= NULL ;
229 	if (pNode != NULL)
230 		pNode->m_pLeft	= pEntMutex ;
231 	return	True ;
232 }
233 
234 Boolean
lispMgr_registerNamedMutex(register TLispManager * pLispMgr,register TLispEntity * pEntMutex)235 lispMgr_registerNamedMutex (
236 	register TLispManager*	pLispMgr,
237 	register TLispEntity*	pEntMutex)
238 {
239 	register TLispEntity*	pNode ;
240 	register TLispEntity*	pPrevNode ;
241 	register TLispMutex*	pMutex ;
242 	register TLispMutex*	pNodeMutex ;
243 	register const Char*	pMutexName ;
244 	register int			nMutexName ;
245 	register const Char*	pNodeMutexName ;
246 	register int			nNodeMutexName ;
247 	register int			nCompare, nDiff ;
248 
249 	assert (pLispMgr != NULL) ;
250 	assert (pEntMutex  != NULL) ;
251 	assert (pEntMutex->m_iType == LISPENTITY_MUTEX) ;
252 
253 	pMutex		= lispEntity_GetMutexPtr (pEntMutex) ;
254 	pMutexName	= pMutex->m_achString ;
255 	nMutexName	= pMutex->m_nLength ;
256 	assert (pMutexName != NULL && nMutexName > 0) ;
257 
258 	pNode		= pLispMgr->m_pEntListNamedMutex ;
259 	pPrevNode	= NULL ;
260 	while (pNode != NULL) {
261 		pNodeMutex		= lispEntity_GetMutexPtr (pNode) ;
262 		pNodeMutexName	= pNodeMutex->m_achString ;
263 		nNodeMutexName	= pNodeMutex->m_nLength ;
264 		/*	�������¤�Ǥ����ΤȤ��Ƥ��롣*/
265 		nCompare		= (nMutexName < nNodeMutexName)? nMutexName : nNodeMutexName ;
266 		nDiff			= Cstrncmp (pMutexName, pNodeMutexName, nCompare) ;
267 		assert (!(nDiff == 0 && nMutexName == nNodeMutexName)) ;
268 		if (nDiff > 0 || (nDiff == 0 && nMutexName > nNodeMutexName))
269 			break ;
270 		pPrevNode		= pNode ;
271 		pNode			= pNode->m_pRight ;
272 	}
273 	if (pPrevNode == NULL) {
274 		pEntMutex->m_pRight	= pLispMgr->m_pEntListNamedMutex ;
275 		pLispMgr->m_pEntListNamedMutex	= pEntMutex ;
276 	} else {
277 		pPrevNode->m_pRight	= pEntMutex ;
278 	}
279 	pEntMutex->m_pLeft	= pPrevNode ;
280 	pEntMutex->m_pRight	= pNode ;
281 	if (pNode != NULL)
282 		pNode->m_pLeft	= pEntMutex ;
283 	return	True ;
284 }
285 
286 void
lispMgr_abondonMutexSub(register TLispManager * pLispMgr,register TLispEntity * pEntListTop,register const void * pOwner)287 lispMgr_abondonMutexSub (
288 	register TLispManager*	pLispMgr,
289 	register TLispEntity*	pEntListTop,
290 	register const void*	pOwner)
291 {
292 	register TLispEntity*	pNode ;
293 	register TLispMutex*	pNodeMutex ;
294 
295 	pNode		= pEntListTop ;
296 	while (pNode != NULL) {
297 		pNodeMutex		= lispEntity_GetMutexPtr (pNode) ;
298 		if (pNodeMutex->m_pOwner == pOwner) {
299 			pNodeMutex->m_pOwner		= NULL ;
300 			pNodeMutex->m_uLockCount	= 0;
301 		}
302 		pNode			= pNode->m_pRight ;
303 	}
304 	return ;
305 }
306 
307