How to make SetTimer() only send one WM_TIMER message? http://stackoverflow.com/questions/29135417/how-to-make-settimer-only-... [stackoverflow.com] > SetTimer() creates a periodic timer only. The only way to make it a one-shot timer is to kill the timer on the first WM_TIMER message, as you are already doing. > Otherwise, change your timer logic so you can use CreateWaitableTimer() or timeSetEvent() instead, both of which can create a true one-sho
なんかよくわかんないけど (スコア:0)
ずいぶんと複雑なシステムなんですね。
Re:なんかよくわかんないけど (スコア:2, 興味深い)
複雑というよりは、「今どきのOSや開発環境では考えられない」問題のような。
前者は「デッドロック」に類されるトラブルでしょうが、お互いに同じ資源を奪い合っているのであればともかく、外部デバイスとのインターフェイス処理と内部的な処理でそれが発生するとは考えにくいですし、もしそうであるとしたら、「お前らテストしてないだろ」って言われても仕方のないくらい、根本部分のバグのような気がします。よく言われる「枯れていない」(=十分にフィールドテストされていない)環境で発生するトラブルと思われます。
後者は「不正ポインタ参照」に類されるトラブルと思われますが、こちらも十分にテストされた高水準言語を使用していれば、最初から避けられたトラブルのような気がします。
Re:なんかよくわかんないけど (スコア:2, 興味深い)
日経BPの絵をちょっと見たけど、確かにあまり普通のWebエンジニアにはお目にかからないものかも
中継サーバのレイヤー構成の中に耐タンパ層ってのがある。で、その中にドライバーという箱の絵もある。
つまり、暗号化・複合化処理っていうのはICカードの耐タンパ処理の(理論処理の)ことらしい。
なんでこれがデバイスドライバーなのかというと、それはつまりICカードメーカがソフトウェアライブラリは(リバースエンジニアリングされるから)出してくれないからだろう。
自分はIAサーバの物理ハードのデバイスドライバは書いたことないのでどれくらいの難易度なのかわからんが、すくなくともコピペすれば出来上がるものではなさそうだ。
ま、実際やれば色々苦労はあるんじゃないか。
この辺からどんどん想像になっていくけど、
そのデバイスドライバの割り込み処理が変で、割り込み入るとうまく動かないらしいね。
じゃぁ、CPU監視の割り込みを止めりゃいいんじゃないのか?毎日使えないよりましだろ?とは思うが。
なにより問題なのは時間がかかってることだよなぁ。そしてその原因が問題解決以外のところに時間使ったのが原因じゃねえのかよ?
ってところがなぁ。日本の技術力は落ちたなぁ。
Re:なんかよくわかんないけど (スコア:1)
日本の技術力は落ちたなぁ。
ネットワークサービス、特に公的機関の提供物に関しては元々高い技術力のイメージはないなあ。
洗練されたものを一発で作るよりも、泥臭く工数を掛けて実用に耐えうるように作っていく感じ。
Re: (スコア:0)
レイヤーの図は何かおかしいし、CPU監視は、ただのウォッチドッグタイマーじゃないかなぁ?
Windows Serverのwatchdogの挙動は良く知りませんが、メモリディスクの退避などのためにカーネルパニックしない設定もできるはず。
でも、ウォッチドッグタイマーとなると、因果関係が逆になるので、CPUを弄っても意味無いはず…。
Re: (スコア:0)
皮肉で書いているんだと思う
Re: (スコア:0)
日本の技術力は落ちたなぁ。
そりゃ、これだけ社会全体で冷遇してきたんだから、優秀な人が来ないし。
Re: (スコア:0)
後者はマルチスレッド間のリソース共有という、超基本ができてなかったという問題に見える。
高水準言語でもロック機構使わずに回避は無理。
前者はわからないな。encrypt/decrypt deviceがDisable Interruptかけずに割り込まれて固まったようにも聞こえるけど、やっぱ記事からだけじゃわからん。
Re:なんかよくわかんないけど (スコア:1)
報道資料「カード管理システムの中継サーバに生じた障害原因の特定と対応について」 [j-lis.go.jp](PDF)から抜粋
原因2
(説明)通常、業務アプリケーションがデータ処理を開始する際に、メモリ内に作業領域を確保してから処理を行う。ところが、業務アプリケーションがデータ処理を開始する前にWindowsからタイムアウトの通知を受け取った場合、終了処理が実行され、メモリ内に作業領域を確保していないにも関わらず存在しない作業領域を解放しようとして、業務アプリケーションが異常終了する
#3006932 [it.srad.jp]が指摘するように不正ポインタ参照でしょうね。
ただ、終了時に開放リソースのnullチェックしてなかったってだけと思えるような説明だけども。
Re:なんかよくわかんないけど (スコア:2)
タイムアウトの通知を受けるよりも過去に、作業領域を確保するだけで済みそうな。
ケチるような場面でもないだろうし。
それと、常識的に考えて、データ処理とタイムアウト通知受けが別のスレッドで動く事は無い。
Re:なんかよくわかんないけど (スコア:1)
バッドノウハウを指摘されただけのようにも見える。
タイムアウトが来たらアプリは使用不能になる→どうせアプリ止めなきゃならないなら、不正処理例外で殺せば良いんじゃ?
ってパターンもあるかも?
一見トンでもないやり方に見えるが、リソース節減には有効だったりするし。
-- Buy It When You Found It --
Re:なんかよくわかんないけど (スコア:1)
アゴがっくん。
そんな方法があるなんて、思いもしなかった。
目にウロコがはまった。
Re: (スコア:0)
ぬるぽっ!
今時スレッドセーフ意識しないで組むとか有り得ないw
「数(人月)だけ間に合わせ」てシステム組んだんだろうなぁ。
そして、個々のスキルは考慮外と。
炎上するフラグしか見えない…
Re: (スコア:0)
ガッ
#「ぬるぽっ!」って題名のマンガないのかねぇ
Re: (スコア:0)
そのPDFによると、コーナーケースのようですね。
>①タイムアウト通知とタイマリセットが同時に発生した場合、Windowsの仕様上、タイマリセットが行われない場合がある。
>②この場合、タイムアウト通知が保持されたままとなり、アプリケーションがデータ処理開始前にタイムアウト通知を受け取る。
nullチェックだけで防げたかというと、どうでしょう。終了処理とタイムアウト通知が運悪く重なると、タイミングによってはnullチェックも突破しそうなような…。いや、でも、図のように終了処理の後までタイムアウト通知を保持するのかなぁ?
処理完了の前にビジーになると「同時」でなくてもメッセージが溜まる (スコア:2)
ソースコード実物を見ないと分かりませんが、この説明はおそらく図のほうが正しく(実挙動に近く)、文章の方が不正確です。
「タイマリセット」に使っているのは、多分このAPIでしょう。
https://msdn.microsoft.com/ja-jp/library/cc410876.aspx [microsoft.com]
とあります。これはWindows罠仕様の一つです。
「タイマリセットが行われない場合がある」ではなく、KillTimer関数が呼ばれるまでの間にタイムアウトすると、タイムアウトのメッセージが削除されない事による現象です。
これ、もう一つ罠があって、『中継処理の完了』メッセージを受け取る前のタイミングで何か別の処理が走りだしてビジーになっていて、『中継処理の完了』メッセージが保留されていると、その間にタイムアウトする可能性があるって事なんですね。
ですので、この問題が発生するタイミングは「同時に発生」どころか、数秒(数分)に渡る可能性があります。
(遅延がひどいと2度も3度もタイムアウトを受け取ります。タイマはリピートするので)
レアなケースではなく、運用環境では頻繁に起きるものと考える必要があります。(そして実際起きた)
Re: (スコア:0)
情報ありがとうございます。けれど、SetTimerを使ってリピートさせる必要は無いような…。
How to make SetTimer() only send one WM_TIMER message?
http://stackoverflow.com/questions/29135417/how-to-make-settimer-only-... [stackoverflow.com]
> SetTimer() creates a periodic timer only. The only way to make it a one-shot timer is to kill the timer on the first WM_TIMER message, as you are already doing.
> Otherwise, change your timer logic so you can use CreateWaitableTimer() or timeSetEvent() instead, both of which can create a true one-sho
Re: (スコア:0)
NTTコムかぁ。。
あそこ、Webシステム開発ですらネット禁止だったりするからリファレンス確認という超基本すら出来なかったかも。
まあ、それ以前にタイマーに依存した仕組みで作る発想がどうかと思うが、イベント駆動思想無いとこだしなあ。。。
Re: (スコア:0)
うーん、これってWindows側から見れば当然の仕様で、別に罠でもなんでもなく、
GUIアプリでの利用を想定したSetTimer()を使うこと自体がおかしいように見えます。
ウィンドウメッセージはアプリ側で主体的に受け取りにいかないといけないものなんだから、
メッセージの発信から受け取りまでにタイムラグが発生するのは当然。
そのタイムラグによって同期エラーが発生するのは不思議でもなんでもなく、設計段階で当然考慮すべきものに思えます。
そもそも、アプリ側で主体的に受け取りに行く必要がある(=メッセージループを回してメッセージをチェックするコードを書く必要がある)と
Re: (スコア:0)
さすがにSetTimerのタイマーなんて使うわけないでしょー。おもちゃじゃないんだから。
WaitForSingleObjectとかのタイムアウトだと思いますよ。
Re: (スコア:0)
今時のアプリ開発はフレームワーク使って、ウィンドウメッセージを明示的に取りに行くコードは
書かないと思うんですけどね。
それが問題だって話ならわかるんですけどね・・・
Re: (スコア:0)
と、思ったら、「タイマリセット」と書いてある...。うそでしょ..。
SetEventのことを言っていると思いたい。
Re: (スコア:0)
確実に処理しないといけない部分に、ウィンドウメッセージを使って処理要求をしていること自体もおかしいと思います。
関数呼び出しやイベント待ちの受け渡しとは違って、ウィンドウメッセージは失敗する可能性がありますから。
キューイングされるメッセージの最大数とか想像してみましょう。
Re: (スコア:0)
# 複数雑なところがあるシステムだって皮肉なのでは。。。
Re: (スコア:0)
複雑というよりは、「今どきのOSや開発環境では考えられない」問題のような。
うん、単純に組んでいればこんなこと起きないかなと。なので随分と複雑だと思いました。