新規記事の投稿を行うことで、非表示にすることが可能です。
2014年05月30日
サーバ方式ではないログの多重追記方式を考えてみる
同じログ出力ライブラリを使用していて、たまたま同じファイル名になる場合というのも、結構あったりする
こうした際、通常は先にログファイルをオープンしている方が排他的にファイルに書き込むことができえるわけだ
ところが、こうした方式の場合、同じファイル名だと、後から書こうとしていたプロセスのログが失われててしまう
度々非同期に呼ばれるコマンドが、同じログファイルを使用していると、こうしたことになってしまい、後から解析するのに困ってしまうわけだ
とりあえず、Win32 に限って考えてみると、 LockFile API が何となく使えそうな気がした
例えば次のようなインタフェースでログを書くとする
書き込み動作の最終インターフェースがこうした形式であれば、ファイルの最後の領域をロックして、そのロックした両機に指定サイズのデータを書き込めば、うまくいくのではないかと思えた
そこで、次のようなコードを考えてみた
一見これでうまく行きそうに見えたのだが、残念ながらうまくいかず、ファイルの書き込みがオーバーラップしてしまっていた
重なった領域はロックできないと思ったのだが、先頭部分のロック獲得ループがあっさりと抜けてしまい、前のプロセスの書き込み途中から上書きするようになってしまった
もう少し工夫しないといけなさそうだ
こうした際、通常は先にログファイルをオープンしている方が排他的にファイルに書き込むことができえるわけだ
ところが、こうした方式の場合、同じファイル名だと、後から書こうとしていたプロセスのログが失われててしまう
度々非同期に呼ばれるコマンドが、同じログファイルを使用していると、こうしたことになってしまい、後から解析するのに困ってしまうわけだ
とりあえず、Win32 に限って考えてみると、 LockFile API が何となく使えそうな気がした
例えば次のようなインタフェースでログを書くとする
void write(void* buffer, size);
書き込み動作の最終インターフェースがこうした形式であれば、ファイルの最後の領域をロックして、そのロックした両機に指定サイズのデータを書き込めば、うまくいくのではないかと思えた
そこで、次のようなコードを考えてみた
void CWin32Logger::write(void* buffer, DWORD size)
{
DWORD dwSize = GetFileSize(m_hFile, NULL);
while (!LockFile(m_hFile, dwSize, 0, size, 0)) {
Sleep(10);
dwSize = GetFileSize(m_hFile, NULL);
}
if (INVALID_SET_FILE_POINTER != SetFilePointer(m_hFile, 0, NULL, FILE_END)) {
DWORD sz;
if (WriteFile(m_hFile, buffer, size, &sz, NULL)) {
m_dwLoPos = dwSize + size;
FlushFileBuffers(m_hFile);
SetEndOfFile(m_hFile);
}
} else {
TCHAR msg[256] = {0};
wsprintf(msg, _T("%d\r\n"), GetLastError());
OutputDebugString(msg);
}
UnlockFile(m_hFile, dwSize, 0, size, 0);
}
一見これでうまく行きそうに見えたのだが、残念ながらうまくいかず、ファイルの書き込みがオーバーラップしてしまっていた
重なった領域はロックできないと思ったのだが、先頭部分のロック獲得ループがあっさりと抜けてしまい、前のプロセスの書き込み途中から上書きするようになってしまった
もう少し工夫しないといけなさそうだ
【このカテゴリーの最新記事】
-
no image
-
no image
-
no image
-
no image
-
no image
2014年05月29日
Shell_NotifyIcon がエラー 0 を返す
PC起動時に動き出すプログラムを開発しているが、通知エリア(昔はタスクトレイとも言っていた) にアイコンを登録するために Shell_NotifyIcon API を使用するが、PC起動時の忙しい時には、結構失敗していることがわかった
http://nyaruru.hatenablog.com/entry/20071008/p3 でも紹介されていたが、 API が FALSE を返したときに GetLastError() でエラーコードを取得すると、 ERROR_TIMEOUT (1460) が返ると説明されているが、自分のプログラムのログを調べると、ERROR_SUCCESS (0) が返ってきており、よくわからない状況となっている
実際上、想像するに、アプリケーション全体がハングアップするのを防ぐ目的で、タイムアウトしているというのが起きているのは間違いないだろうと思っているのだが、 Windows 7 になってからなのか、ERROR_SUCCESS が返ってきているのに違和感を覚えている
いずれにせよエラーには違いないのだろうから、リトライするなどの処置が必要とは思うが、アイコンの変更だけで何秒も待たさせるのも嫌な話だ
今のところは適当に5回程度リトライしてもだめなら、ログを出して無視するという対処にしてあるが、こういうのが解決することはあるのだろうか?
http://nyaruru.hatenablog.com/entry/20071008/p3 でも紹介されていたが、 API が FALSE を返したときに GetLastError() でエラーコードを取得すると、 ERROR_TIMEOUT (1460) が返ると説明されているが、自分のプログラムのログを調べると、ERROR_SUCCESS (0) が返ってきており、よくわからない状況となっている
実際上、想像するに、アプリケーション全体がハングアップするのを防ぐ目的で、タイムアウトしているというのが起きているのは間違いないだろうと思っているのだが、 Windows 7 になってからなのか、ERROR_SUCCESS が返ってきているのに違和感を覚えている
いずれにせよエラーには違いないのだろうから、リトライするなどの処置が必要とは思うが、アイコンの変更だけで何秒も待たさせるのも嫌な話だ
今のところは適当に5回程度リトライしてもだめなら、ログを出して無視するという対処にしてあるが、こういうのが解決することはあるのだろうか?
2014年05月26日
AWS での電話認証
AWS の Free Tier を試してみようとおもったが、電話認証で躓いてしまったという話
結局、電話認証用のページで、言語設定を日本語にし、電話をかけてもらったら解決した
※12時間も待たなくてよかった
ポイントは、待ち受け電話が携帯電話の場合に、キー入力を認識しない場合があるということ
特に自分の携帯電話はいわゆるガラケーなので、キー入力してもプッシュトーンが再生できていないよう
おそらくそれが原因でキー入力は認識しなかったのだろうと推測している
では、どうやったかというと、音声認識
数字を「日本語」で1文字づつ、ゆっくりと(1文字t1秒くらいからな?)発音したら、ちゃんと認識し、「認証されました」との案内が流れた
※言語設定を English にしたままだったら、英語で発音しなきゃだめだったんだろうな
結局、電話認証用のページで、言語設定を日本語にし、電話をかけてもらったら解決した
※12時間も待たなくてよかった
ポイントは、待ち受け電話が携帯電話の場合に、キー入力を認識しない場合があるということ
特に自分の携帯電話はいわゆるガラケーなので、キー入力してもプッシュトーンが再生できていないよう
おそらくそれが原因でキー入力は認識しなかったのだろうと推測している
では、どうやったかというと、音声認識
数字を「日本語」で1文字づつ、ゆっくりと(1文字t1秒くらいからな?)発音したら、ちゃんと認識し、「認証されました」との案内が流れた
※言語設定を English にしたままだったら、英語で発音しなきゃだめだったんだろうな
2014年05月24日
テスト用のサーバを準備したい
AWS 用の環境設定のために、サーバを準備したいということになった
AWS を直接申し込んだが、PIN 確認に規定回数以上失敗し、12時間待ちとなってしまった
12時間も遊んで待っているのもいやなので、手っ取り早く、いつも使っているサーバを準備しようかと思いった
AWS を直接申し込んだが、PIN 確認に規定回数以上失敗し、12時間待ちとなってしまった
ここの仕様もちょっと不親切だと感じた
最初の電話のトライで、勝手がわからず、音声で答えるのかと思っていたら、切られてしまい、WEB画面上は電話番号がクリアされてしまった
この時、国番号もUSに初期化されてしまっているのを見落として、何度もリコールに失敗してしまい、もうリトライできない状況になってしまった
12時間も遊んで待っているのもいやなので、手っ取り早く、いつも使っているサーバを準備しようかと思いった
タグ:サーバ