* copy vendor drop to trunk
[lab.git] / Dev / utvpn / utvpn-unix-v101-7101-public / src / Mayaqua / Object.c
1 // SoftEther UT-VPN SourceCode\r
2 // \r
3 // Copyright (C) 2004-2010 SoftEther Corporation.\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.\r
6 // All Rights Reserved.\r
7 // \r
8 // http://utvpn.tsukuba.ac.jp/\r
9 // \r
10 // This program is free software; you can redistribute it and/or\r
11 // modify it under the terms of the GNU General Public License\r
12 // version 2 as published by the Free Software Foundation.\r
13 // \r
14 // This program is distributed in the hope that it will be useful,\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
17 // GNU General Public License for more details.\r
18 // \r
19 // You should have received a copy of the GNU General Public License version 2\r
20 // along with this program; if not, write to the Free Software\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
22 // \r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。\r
28 // \r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって\r
32 // ホストされています。\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、\r
34 // および、試験または研究のために利用が行われることを想定して配布\r
35 // しています。\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に\r
37 // あります。\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース\r
42 // に組み込みさせていただきます。\r
43 // \r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。\r
46 // \r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意\r
51 // ください。\r
52 // \r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、\r
58 // 公益保護にご協力いただきますようお願い申し上げます。\r
59 // \r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客\r
62 // を保護するための努力を行います。\r
63 // \r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/\r
65 // 日本国内の脆弱性情報届出受付公的機関:\r
66 //         独立行政法人 情報処理推進機構\r
67 //         http://www.ipa.go.jp/security/vuln/report/\r
68 // \r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/\r
71 \r
72 // -----------------------------------------------\r
73 // [ChangeLog]\r
74 // 2010.05.20\r
75 //  新規リリース by SoftEther\r
76 // -----------------------------------------------\r
77 \r
78 // Object.c\r
79 // オブジェクト管理コード\r
80 \r
81 #include <stdio.h>\r
82 #include <stdlib.h>\r
83 #include <string.h>\r
84 #include <wchar.h>\r
85 #include <stdarg.h>\r
86 #include <time.h>\r
87 #include <errno.h>\r
88 #include <Mayaqua/Mayaqua.h>\r
89 \r
90 // 試しにロックをかけてみるスレッド\r
91 void CheckDeadLockThread(THREAD *t, void *param)\r
92 {\r
93         DEADCHECK *c = (DEADCHECK *)param;\r
94 \r
95         if (t == NULL || c == NULL)\r
96         {\r
97                 return;\r
98         }\r
99 \r
100         NoticeThreadInit(t);\r
101 \r
102         Lock(c->Lock);\r
103         Unlock(c->Lock);\r
104         c->Unlocked = true;\r
105 }\r
106 \r
107 // デッドロックの検出\r
108 void CheckDeadLock(LOCK *lock, UINT timeout, char *name)\r
109 {\r
110         DEADCHECK c;\r
111         THREAD *t;\r
112         char msg[MAX_PATH];\r
113 \r
114         if (lock == NULL)\r
115         {\r
116                 return;\r
117         }\r
118         if (name == NULL)\r
119         {\r
120                 name = "Unknown";\r
121         }\r
122 \r
123         Format(msg, sizeof(msg), "error: CheckDeadLock() Failed: %s\n", name);\r
124 \r
125         Zero(&c, sizeof(c));\r
126         c.Lock = lock;\r
127         c.Timeout = timeout;\r
128         c.Unlocked = false;\r
129 \r
130         t = NewThread(CheckDeadLockThread, &c);\r
131         WaitThreadInit(t);\r
132         if (WaitThread(t, timeout) == false)\r
133         {\r
134                 if (c.Unlocked == false)\r
135                 {\r
136                         // デッドロック発生\r
137                         AbortExitEx(msg);\r
138                 }\r
139                 else\r
140                 {\r
141                         WaitThread(t, INFINITE);\r
142                 }\r
143         }\r
144 \r
145         ReleaseThread(t);\r
146 }\r
147 \r
148 // ロックオブジェクトの作成\r
149 LOCK *NewLockMain()\r
150 {\r
151         LOCK *lock;\r
152         UINT retry = 0;\r
153 \r
154         while (true)\r
155         {\r
156                 if ((retry++) > OBJECT_ALLOC__MAX_RETRY)\r
157                 {\r
158                         AbortExitEx("error: OSNewLock() failed.\n\n");\r
159                 }\r
160                 lock = OSNewLock();\r
161                 if (lock != NULL)\r
162                 {\r
163                         break;\r
164                 }\r
165                 SleepThread(OBJECT_ALLOC_FAIL_SLEEP_TIME);\r
166         }\r
167 \r
168         return lock;\r
169 }\r
170 LOCK *NewLock()\r
171 {\r
172         LOCK *lock = NewLockMain();\r
173 \r
174         // KS\r
175         KS_INC(KS_NEWLOCK_COUNT);\r
176         KS_INC(KS_CURRENT_LOCK_COUNT);\r
177 \r
178         return lock;\r
179 }\r
180 \r
181 // ロックオブジェクトの削除\r
182 void DeleteLock(LOCK *lock)\r
183 {\r
184         // 引数チェック\r
185         if (lock == NULL)\r
186         {\r
187                 return;\r
188         }\r
189 \r
190         // KS\r
191         KS_INC(KS_DELETELOCK_COUNT);\r
192         KS_DEC(KS_CURRENT_LOCK_COUNT);\r
193 \r
194         OSDeleteLock(lock);\r
195 }\r
196 \r
197 // ロック\r
198 bool LockInner(LOCK *lock)\r
199 {\r
200         // 引数チェック\r
201         if (lock == NULL)\r
202         {\r
203                 return false;\r
204         }\r
205 \r
206         // KS\r
207         KS_INC(KS_LOCK_COUNT);\r
208         KS_INC(KS_CURRENT_LOCKED_COUNT);\r
209 \r
210         return OSLock(lock);\r
211 }\r
212 \r
213 // ロック解除\r
214 void UnlockInner(LOCK *lock)\r
215 {\r
216         // 引数チェック\r
217         if (lock == NULL)\r
218         {\r
219                 return;\r
220         }\r
221 \r
222         // KS\r
223         KS_INC(KS_UNLOCK_COUNT);\r
224         KS_DEC(KS_CURRENT_LOCKED_COUNT);\r
225 \r
226         OSUnlock(lock);\r
227 }\r
228 \r
229 // カウンタの作成\r
230 COUNTER *NewCounter()\r
231 {\r
232         COUNTER *c;\r
233 \r
234         // メモリ確保\r
235         c = Malloc(sizeof(COUNTER));\r
236 \r
237         // 初期化\r
238         c->Ready = true;\r
239         c->c = 0;\r
240 \r
241         // ロック作成\r
242         c->lock = NewLock();\r
243 \r
244         // KS\r
245         KS_INC(KS_NEW_COUNTER_COUNT);\r
246 \r
247         return c;\r
248 }\r
249 \r
250 // カウンタの削除\r
251 void DeleteCounter(COUNTER *c)\r
252 {\r
253         // 引数チェック\r
254         if (c == NULL)\r
255         {\r
256                 return;\r
257         }\r
258 \r
259         // KS\r
260         KS_INC(KS_DELETE_COUNTER_COUNT);\r
261         KS_SUB(KS_CURRENT_COUNT, c->c);\r
262 \r
263         DeleteLock(c->lock);\r
264         Free(c);\r
265 }\r
266 \r
267 // カウント値の取得\r
268 UINT Count(COUNTER *c)\r
269 {\r
270         UINT ret;\r
271         // 引数チェック\r
272         if (c == NULL)\r
273         {\r
274                 return 0;\r
275         }\r
276         if (c->Ready == false)\r
277         {\r
278                 return 0;\r
279         }\r
280 \r
281         Lock(c->lock);\r
282         {\r
283                 if (c->Ready == false)\r
284                 {\r
285                         ret = 0;\r
286                 }\r
287                 else\r
288                 {\r
289                         ret = c->c;\r
290                 }\r
291         }\r
292         Unlock(c->lock);\r
293 \r
294         return ret;\r
295 }\r
296 \r
297 // インクリメント\r
298 UINT Inc(COUNTER *c)\r
299 {\r
300         UINT ret;\r
301         // 引数チェック\r
302         if (c == NULL)\r
303         {\r
304                 return 0;\r
305         }\r
306         if (c->Ready == false)\r
307         {\r
308                 return 0;\r
309         }\r
310 \r
311         Lock(c->lock);\r
312         {\r
313                 if (c->Ready == false)\r
314                 {\r
315                         ret = 0;\r
316                 }\r
317                 else\r
318                 {\r
319                         c->c++;\r
320                         ret = c->c;\r
321                 }\r
322         }\r
323         Unlock(c->lock);\r
324 \r
325         // KS\r
326         KS_INC(KS_INC_COUNT);\r
327         KS_INC(KS_CURRENT_COUNT);\r
328 \r
329         return ret;\r
330 }\r
331 \r
332 // デクリメント\r
333 UINT Dec(COUNTER *c)\r
334 {\r
335         UINT ret;\r
336         // 引数チェック\r
337         if (c == NULL)\r
338         {\r
339                 return 0;\r
340         }\r
341         if (c->Ready == false)\r
342         {\r
343                 return 0;\r
344         }\r
345 \r
346         Lock(c->lock);\r
347         {\r
348                 if (c->Ready == false)\r
349                 {\r
350                         ret = 0;\r
351                 }\r
352                 else\r
353                 {\r
354                         if (c->c != 0)\r
355                         {\r
356                                 c->c--;\r
357                                 ret = c->c;\r
358                         }\r
359                         else\r
360                         {\r
361                                 ret = 0;\r
362                         }\r
363                 }\r
364         }\r
365         Unlock(c->lock);\r
366 \r
367         // KS\r
368         KS_INC(KS_DEC_COUNT);\r
369         KS_DEC(KS_CURRENT_COUNT);\r
370 \r
371         return ret;\r
372 }\r
373 \r
374 \r
375 // 参照カウンタの解放\r
376 UINT Release(REF *ref)\r
377 {\r
378         UINT c;\r
379         // 引数チェック\r
380         if (ref == NULL)\r
381         {\r
382                 return 0;\r
383         }\r
384 \r
385         // KS\r
386         KS_INC(KS_RELEASE_COUNT);\r
387         KS_DEC(KS_CURRENT_REFED_COUNT);\r
388 \r
389         c = Dec(ref->c);\r
390         if (c == 0)\r
391         {\r
392                 // KS\r
393                 KS_DEC(KS_CURRENT_REF_COUNT);\r
394                 KS_INC(KS_FREEREF_COUNT);\r
395 \r
396                 DeleteCounter(ref->c);\r
397                 ref->c = 0;\r
398                 Free(ref);\r
399         }\r
400         return c;\r
401 }\r
402 \r
403 // 参照カウンタの増加\r
404 UINT AddRef(REF *ref)\r
405 {\r
406         UINT c;\r
407         // 引数チェック\r
408         if (ref == NULL)\r
409         {\r
410                 return 0;\r
411         }\r
412 \r
413         c = Inc(ref->c);\r
414 \r
415         // KS\r
416         KS_INC(KS_ADDREF_COUNT);\r
417         KS_INC(KS_CURRENT_REFED_COUNT);\r
418 \r
419         return c;\r
420 }\r
421 \r
422 // 参照カウンタ作成\r
423 REF *NewRef()\r
424 {\r
425         REF *ref;\r
426 \r
427         // メモリ確保\r
428         ref = Malloc(sizeof(REF));\r
429 \r
430         // カウンタ作成\r
431         ref->c = NewCounter();\r
432 \r
433         // 1 回だけインクリメント\r
434         Inc(ref->c);\r
435 \r
436         // KS\r
437         KS_INC(KS_NEWREF_COUNT);\r
438         KS_INC(KS_CURRENT_REF_COUNT);\r
439         KS_INC(KS_ADDREF_COUNT);\r
440         KS_INC(KS_CURRENT_REFED_COUNT);\r
441 \r
442         return ref;\r
443 }\r
444 \r
445 // イベントオブジェクトの作成\r
446 EVENT *NewEvent()\r
447 {\r
448         // メモリ確保\r
449         EVENT *e = Malloc(sizeof(EVENT));\r
450 \r
451         // 参照カウンタ\r
452         e->ref = NewRef();\r
453 \r
454         // イベント初期化\r
455         OSInitEvent(e);\r
456 \r
457         // KS\r
458         KS_INC(KS_NEWEVENT_COUNT);\r
459 \r
460         return e;\r
461 }\r
462 \r
463 // イベントの解放\r
464 void ReleaseEvent(EVENT *e)\r
465 {\r
466         // 引数チェック\r
467         if (e == NULL)\r
468         {\r
469                 return;\r
470         }\r
471 \r
472         if (Release(e->ref) == 0)\r
473         {\r
474                 CleanupEvent(e);\r
475         }\r
476 }\r
477 \r
478 // イベントの削除\r
479 void CleanupEvent(EVENT *e)\r
480 {\r
481         // 引数チェック\r
482         if (e == NULL)\r
483         {\r
484                 return;\r
485         }\r
486 \r
487         // イベント解放\r
488         OSFreeEvent(e);\r
489 \r
490         // メモリ解放\r
491         Free(e);\r
492 \r
493         // KS\r
494         KS_INC(KS_FREEEVENT_COUNT);\r
495 }\r
496 \r
497 // イベントのセット\r
498 void Set(EVENT *e)\r
499 {\r
500         // 引数チェック\r
501         if (e == NULL)\r
502         {\r
503                 return;\r
504         }\r
505 \r
506         OSSetEvent(e);\r
507 }\r
508 \r
509 // イベントの待機\r
510 bool Wait(EVENT *e, UINT timeout)\r
511 {\r
512         // 引数チェック\r
513         if (e == NULL)\r
514         {\r
515                 return false;\r
516         }\r
517 \r
518         // KS\r
519         KS_INC(KS_WAIT_COUNT);\r
520 \r
521         return OSWaitEvent(e, timeout);\r
522 }\r
523 \r
524 \r
525 \r