source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Object.c @ a1bae3e

trunk
Last change on this file since a1bae3e was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

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