Let’s note CF-S10をリフレッシュサービスに送り出しました

2011年に買った Let’s note CF-S10EYTDR ですが、
申し込み期限が 今月16日に迫っていたので ついにリフレッシュサービスに出しました。

続きを読む Let’s note CF-S10をリフレッシュサービスに送り出しました

adbがデバイスを認識してくれない時

毎回忘れてる気がするので備忘録がわりに・・・

USBデバッグ がオンになってて ADBドライバも正しくインストールされているのに “adb devices” で端末が出てこない場合、 まず端末側に 「USBデバッグを許可しますか?」と確認が出てないか確認します。

これが出てればあとは「OK」ってすれば終了なんですが、これが出ない場合。

USB転送モードを変更するとだいたい出るようになります。
USB転送モードは機種・Androidのバージョンによってたぶん呼び方違います。
Nexus5X の場合、「USBの使用」になってました。

PCと端末をUSBでつなぐと、「USBデバッグ接続されましたー」というのとは別に、通知にどの転送モードになっているか表示されるので、これをタップして転送モードを変更します。

Nexus 5X の場合は最初 「充電」に設定されているのでこれを 「写真の転送 (PTP)」 に設定します。
すると 「許可しますかー」が出てきました。

Nexus5 の場合は逆にMTPにしないとダメだったような・・・

あと、以前 そもそもつなげてもUSBデバッグにならなくて困ったことがあったんですが、その時は何故かUSBのポートを変えたら認識しました。

bashでシグナルを使った同期

最近こんなの書きました。

やりたいことは、

  • webサーバーでリクエストを受け取ったら少量のデータ(メッセージ)をDBに格納してすぐレスポンスを返す
  • 同時にバックグランドで複雑な処理をしてDBに反映する
  • バックグラウンドで処理中に複数のメッセージがあった場合はまとめて処理できるようにする
  • リクエストがなくても一定時間毎にバックグランド処理を実行したい

です。

Producer-Consumer的な?
簡単なメッセージキュー?のようなものをbashだけでできます。
(リクエストを受けるのとバックグランドでの処理は別途必要です)

syncrun.sh


#! /bin/bash

function wakeup {
    wakeup=yes
}

function stop {
    stop=yes
}

function loop {
    while true; do
        sleep $sec
        kill -USR1 $mypid
    done
}

# スクリプト終了時にバックグランドで起動したプロセスとpidファイルを削除
function clean {
    kill "$looppid"
    rm -f "$pidfile"
}

sec=60
pidfile=/tmp/syncrun.pid

# オプションの解析
while getopts "s:p:" opt; do
  case $opt in
    s) sec="${OPTARG}" ;;
    p) pidfile="${OPTARG}" ;;
  esac
done

shift $(( $OPTIND - 1 ))

wakeup=yes
stop=no

mypid=$$
echo "mypid=${mypid}"
echo $mypid > $pidfile

# ユーザー定義の割り込み
trap wakeup USR1

# Ctrl+C とか、端末が切り離されたとき
trap stop HUP TERM INT

# スクリプトの終了時
trap clean EXIT

# バックグラウドでループ (新たにプロセスが起動する)
loop &

# ループプロセスのpid
looppid=$!

# "stop"フラグが立っていたらループを抜けて終了
while [[ $stop != yes ]]; do

    # シグナルがあったら指定されたコマンドを実行
    # コマンド実行中にシグナルがたつことがあるので、実行した後もフラグチェック
    # フォアグランドのコマンド実行中はトラップされない。終了時にトラップされる
    while [[ $wakeup == yes ]]; do
        wakeup=no
        command "$@"
    done

    wait # 起動したプロセスの終了を待つ。シグナルで割り込まれる
done

-s オプションで 最大の待機時間、 -p オプションで pid記録するファイルを指定します。
残りの引数は実行するコマンドとその引数です。

最大10秒待機、pidを/tmp/syncrun.pid に記録するように指定して起動

$ bash syncrun.sh -s 10 -p /tmp/syncrun.pid echo hoge

daemon化する場合

$ setsid bash syncrun.sh -s 10 -p /tmp/syncrun.pid echo hoge

待機を中断して処理をさせる

$ kill -USR1 $(cat /tmp/syncrun.pid)

終了

$ kill -HUP $(cat /tmp/syncrun.pid)

使い道としては、DBにとりあえず入れたログを一定時間、一定件数で集計するとか。
特にログをもとに木構造のデータをDB上に構築していくような場合で、木の変更は同期的にやりたいけど、排他ロックはかけたくない、みたいな時に使えるかも。
うまくやればリアルタイムっぽいランキング集計とかできるかもしれないです。

あとはアップロードされた動画の変換処理とかですね。

upload-video.php

<php
function get_converter_pid() {
    (略) // pidファイルを読んで返す
}

function notify_uploaded() {
    if (($pid = get_converter_pid()) == false) {
        return false;
    }

    posix_kill($pid, SIGUSR1);
}

(略)

move_uploaded_file ($_FILES['videofile']['temp_name'], $dest);
$stmt = $pdo->prepare('insert into videos (file, state, date) values(:file, "uploaded", :date)');
$stmt->execute(array(':file' => $dest, ':date' => date('Y-m-d H:i:s')));

notify_uploaded();

(略)

convert-video.php


function fetch_uploaded_video() {
    (略)
}

/*
    return true if state changed or return false
*/
function update_video_state($video_id, $state) {
    (略)
}

function update_converted_video($video_id, $file, $state='converted') {
    (略)
}

/*
    変換された動画のファイルのパスを返す
*/
function convert_video_format($in_filename) {
    (略) // ffmpeg とかつかって全力で変換します
}

list($video_id, $video_file) = fetch_uploaded_video();

if (!empty($video_id) && update_video_state($video_id, "processing")) {
    $out_file = convert_video_format($video_file);
    update_converted_video($video_id, $out_file);
}

(略)
$ setsid bash syncrun.sh -s 60 -p /tmp/videoconverter.pid php /PATH/TO/convert_video.php

シグナル以外にも、名前付きパイプ(FIFO)を使うとか、
inotify でディレクトリを監視するとか、
他にもやりかたがありますです。

ファイルがアップロードされたらrsyncするとかは、inotify版でやったほうが楽だと思いますです。

しかしそもそもbashでやる必要があったのか(笑)

goclipseとApp Engine

eclipseでGo言語書きたい。そして GAEにデプロイしたい。

普通にgoclipseの設定すると、appengine以下のパッケージを認識できずエラーになり、コード補完も効きません。
Projectの”Build Automatically” を On にしていると保存するたびに怒られます。

続きを読む goclipseとApp Engine

Bisonで再入可能な構文解析器を作る(C言語版)

前回作った電卓プログラムは、Bisonが吐き出した main.tab.c というCのコードをコンパイルしてリンクしています。
中を見ると、yyparse関数の中でグローバル変数 “yychar” を初期化したり、字句解析器によって切り出されたトークンを代入したりしているので、このyyparseは再入可能ではありません。つまり、スレッドセーフではないということになります。
(他にも、グローバル変数yylvalを介して 字句解析器とやりとりしてたりします。)

Bisonが再入可能なコードを吐くようにするやりかたは次の2つ。

  • 再入可能なCのコードを出力させる
  • C++のコードを出力させる

今回は1つ目の方法をとります。
続きを読む Bisonで再入可能な構文解析器を作る(C言語版)

久々にBison/Flex

簡単なDSLのスレッドセーフな構文解析エンジンを作る必要ができたので、いろいろ調べつつメモ。
構文解析器はBison、字句解析はFlexに作ってもらいます。
かなり昔に、”ぼくのかんがえたさいきょうのぷろぐらみんぐげんご”のソースを標準入力から読み込み、”ぼくのかんがえたさいきょうのぶいえむ”用のバイトコードを出力するプログラムを作ったことがあったので、Bison/Flex についてはなんとなく覚えています。

今回作るのは、

  • ポートをLISTEN
  • 接続を確立したらスレッド分岐
  • 設計したDSLで書かれたプログラムを受信し、結果を送信する。

というものです。

ですので、構文解析エンジンは最低限次のことを満たす必要があります。

  • 入力はファイルからではなく、文字列、文字バッファ、またはストリームから
  • 出力はストリームに
  • スレッドセーフ(再入可能)

続きを読む 久々にBison/Flex

サポートライブラリ版ActionBarにActionItemを追加する

3.0以降の標準のActionBar (android.app.ActionBar) を使うなら、
何も考えなくても従来通り onCreateOptionsMenu(Menu menu) でメニューをリソースから展開すればいいだけなのだけど、
サポートライブラリ版のActionBar (android.support.v7.app.ActionBar) だと 2.3以前のデバイスで見たときにこんな感じに。。

20130905-122057

メニューキーを押すと出てくる従来型のメニューです。
アクションバーの上には表示されない。

続きを読む サポートライブラリ版ActionBarにActionItemを追加する