ひとつめの失敗
DAブラックホール1.7に実装するキモのひとつに「ダブルタップ」があった。
これは2つの回線(あるいはキャリア)を使って、同時にひとつの番号を解析する機能である。
この機能があれば、一挙動で「キャリア判定」のアタリをつけられ時間短縮になるほか、同一の回線に同時に発呼することで、たとえば iナンバーやダイヤルインで割り当てられている回線数を見つけることができる。
DA電研で使用している回線解析システム「KONDERU-NDA」に実装済みで、実績もあった。
2014年1月頃、いよいよこれを1.7に実装したところ、
「なぜか 2回線のうち 1回線ずつ解析(発呼)が実施される」
という事態に直面した。
A、Bの2回線で同時に解析処理を実行しているのに、Aの解析が終わってから Bの解析がはじまる、という具合だった。
調べてみると、シリアルポートを制御するMSCommコントロール→Win32通信API→ドライバの経路のどこかで、片方の処理に待機がかけられていた。
そのため片方の解析が進行し、終了すると、待機していた側の動作が再開するという状態だった。
VB6.0特有の問題
原因は、以下の2つが考えられた。
- コントロールのスレッド処理の不具合
スレッドセーフでない部分がどこかにあるのだろう、と推測した。 - VB6.0のクラス継承の不具合
この時点で初めて知ったのだが VB6.0ではクラス継承が事実上できない。インターフェースの継承はできるとされているが、実装の継承ができないのである。(それで継承っていえるのかな)
それにもかかわらず、なぜか同じコントロールを複数配置することはできる。配列にすらできる。それらがプロセスならともかく、ハードウェアが絡んだ時に、どういう理屈で処理されているのかいまいちわからないところがある
もとをいえば、MSCommコントロールはWindows3.1 ・1992年のVB2.0からあるコントロールで、つまり16bitだった頃から受け継がれている。
時代背景を考えればスレッドセーフでなくても不思議ではない。というか当然なのかもしれない。
いずれにせよ、この問題の解決には API(DLL)を自分で最初から作る必要があるかもしれなかった。そして、それは時間的に現実的な解ではなかった。
「KONDERU-NDA」での実装は、.net の SerialPort クラス(スレッドセーフ)を使っていたこともあって、この問題は生じていなかった。
まったく、うかつだった。
1.7の保守ストリーム中に解決策が浮かべば対応することにはしたので、
- dablack.accdb には、Book1 と Book2の 2つのテーブル
- 拡張用のSlot (ライセンス認証 入力フォーム)
は、そのまま残すことにした。
「ダブルタップ」は、マルチタップに仕様を変えて実装されることになった。
ダブルタップは 1.8系でも実装する予定はないが、別の機能としてそれに近い動作ができるようにしたいと考えている。
(つづく)