16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"RE:汎用ロックサーバ"
この発言は #01316 TN さんの汎用ロックサーバ に対するコメントです
タイムアウトしたときの処理がいまいちだったので改良したものです。
あと、改行で区切られた複数の文字列について一回の呼び出しでロックを取得
できるようにしています。クライアントの変更は必要なし。
ちなみに、MutexないしはSemaphoe使うとオブジェクトの生成数を減らせて、
COMいじりや自前のキューをしないで済みそうな感じもするのですが、APIを目に
するのがいや(^^; なので、だれかやってくれないかと期待しているんですが..
unit NamedLock;
.....
procedure EnterNamedLock(const LockName: String);
var
i,index: integer;
S: string;
Result: boolean;
WakeupEvent: TSimpleEvent;
St: TStringList;
begin
St := TStringList.Create;
try
St.Text := AnsiUppercase(LockName);
for i := 0 to St.Count-1 do begin
Result := False;
S := St[i];
WakeupEvent := nil;
NLock.Enter;
try
index := Names.IndexOf(S);
if index = -1 then begin // 最初の人がリストを生成
Names.AddObject( S, TList.Create ); // queue of waiting events
Result := True;
end else begin // 次の人からはイベントをキューにつなぐ
WakeupEvent := TSimpleEvent.Create;
TList(Names.Objects[index]).Add( WakeupEvent );
end;
finally
NLock.Leave;
end;
if WakeupEvent <> nil then begin
if WakeupEvent.WaitFor(NORMALMAXWAITTIME) = wrSignaled then begin
Result := True; // (*)
WakeupEvent.Free; // 自分のイベントは自分で消すがキューはもうない
end;
end;
if not Result then begin
LeaveNamedLock( S ); // 自分で追加したキューをつめる
raise ENamedLockException.Create(
'NamedLock Timeout: '+ AnsiUppercase(LockName) );
end;
end;
finally
St.Free;
end;
end;
procedure LeaveNamedLock(const LockName: string);
var
i,index: integer;
S: string;
List: TList;
WakeupEvent: TEvent;
St: TStringList;
begin
St := TStringList.Create;
try
St.Text := AnsiUppercase(LockName);
NLock.Enter;
try
try
for i := St.Count-1 downto 0 do begin
S := St[i];
WakeupEvent := nil;
index := Names.IndexOf(S);
if index <> -1 then begin
List := TList(Names.Objects[index]);
if List.Count = 0 then begin // 自分の後待ちの人は現れなかった
List.Free;
Names.Delete( index );
end else begin // 自分の後に待ちの人がいる
WakeupEvent := List[0]; // 1個だけイベントを取り出して
List.Delete(0); // キューをつめる
end;
end;
if WakeupEvent <> nil then begin // タイムアウトのとき
if WakeupEvent.LastError <> WAIT_OBJECT_0 then
WakeupEvent.Free
else
WakeupEvent.SetEvent // おそらくここで待ち人の(*)に飛ぶ
;
end;
end;
except
end;
finally
NLock.Leave;
end;
finally
St.Free;
end;
end;
TN(CQJ01721)
Original document by TN 氏 ID:(CQJ01721)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|