Linux/Android NDK ソケットメモ

InterlockedIncrement, Decrement, CompareExchange Wrapper

long _InterlockedIncrement(volatile long* Addend)
{
    return __sync_add_and_fetch(Addend, 1);
}

long _InterlockedDecrement(volatile long* Addend)
{
    return __sync_sub_and_fetch(Addend, 1);
}

long _InterlockedCompareExchange(volatile long* Destination, long ExChange, long Comperand)
{
    return __sync_val_compare_and_swap(Destination, ExChange, Comperand);
}

CreateEvent, SetEvent, WaitForSingleObject Wrapper

// CreateEvent
pthread_cond_init(pthread_cond_t* __cond);

// SetEvent
pthread_cond_signal(pthread_cond_t* __cond);

// WaitForSingleObject
pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);

// CloseHandle
pthread_cond_destroy(pthread_cond_t* __cond);

SuspendThread, ResumeThread Wrapper

// SuspendThread
pthread_mutex_lock(pthread_mutex_t* __mutex);

// ResumeThread
pthread_mutex_unlock(pthread_mutex_t* __mutex);

// CloseHandle
pthread_mutex_destroy(pthread_mutex_t* __mutex);

GetCurrentThreadId, Wrapper

unsigned long GetCurrentThreadId()
{
    return pthread_self();
}

マルチスレッドなソケット通信を実装する上でかなり重要なので、メモとして残しておきます。

ついでに、Linuxに限ってですが過去に少しハマった事をメモとして残します。
非同期通信において、Windowsでは送信/受信するデータが存在しない場合、send/recvが-1を返し、SetLastErrorにWSAEWOULDBLOCK のエラーが渡されます。それ以外の場合は他のエラーとなり、エラー処理を行います。
Linuxの場合は、少し仕様が違うようで...(当たり前)
常時、errnoにEWOULDBLOCKがセットされ、接続が確立してる場合は -1を返し、切断されている場合は0を返すようです。


ここまではハマる要素0ですが、、問題は以下の仕様...(ドキュメント見落としで数時間ハマりました。)
クライアントプロセスを落とすと、何故かサーバープロセスも落ちるのです。
例外をキャッチしてみるもうんともすんとも言わず、メモリ違反等であればセグフォが出ますがそれすらも出ません。
どうやら、一度確立されたセッションが切断されると、send/recv内部でSIGPIPEシグナルが発生し、プロセスが強制終了するようです。
対策としては、send/recv関数のオプションにMSG_NOSIGNALを指定し、SIGPIPEシグナルを発生させないようにするか、確立させる前に、signal関数からSIGPIPEシグナルを無効化することで解決できます。


以上、ネタ切れ記事でした。
(Remote Debug対応のARM Debugger があまり進んでいないので、まだ記事に出来ない...社内ツールとして使えるレベルのものに作り上げたい所...)