無理やりgethostbyname をタイマー付で実行する技をiOSで考えてみた

どうも、setjmp / longjmp と alarm がすこぶる相性が悪いみたいなので、alarm だけ使ってできないか考えてみた。

static struct hostent *lpHostEnt = NULL;
typedef struct hostMode{
    char* host; //ターゲット引数
    int timeout; // 函数のタイムアウト
    struct hostent *flag; // ループ用のフラグ
}_hostMode;

static void alarm_func(int erno)
{
    lpHostEnt = NULL;
    printf("gethostbyname: timeout\n");
}

static void* thread(void *arg)
{
    struct hostMode *hm = (struct hostMode*)arg;
    if (lpHostEnt == hm->flag){
        printf("gethostbyname: 警告:まだ前の処理が終わっていません\n");
    } else {
        lpHostEnt = hm->flag;
    }
    pthread_detach(pthread_self()); // スレッドを分離
    signal(SIGALRM, alarm_func);
    alarm(hm->timeout); // タイムアウトの設定
    lpHostEnt = gethostbyname(hm->host);
    signal(SIGALRM, SIG_IGN);
    printf("gethostbyname: function end\n");}

static struct hostent *timeGethostbyname(const char *domain, int timeout)
{
    //threadDomain = (char*)domain;
   
    pthread_t thread_id;
    struct hostMode hm;
    struct hostent dummyHost;
    hm.timeout = timeout;
    hm.host = (char*)domain;
    hm.flag = &dummyHost;
    int rc = pthread_create(&thread_id, NULL , thread, (void*)&hm);
    if(rc == 0){
        pthread_join(thread_id, NULL);
        while(lpHostEnt == &dummyHost);
    }
    return lpHostEnt;
}

原理としては、スレッドを起動して、gethostbyname をalarm 付で 実行
ただし、join したあとスレッドを切り離すので、スレッドはバックグラウンドで動く 
タイムアウトで、返り値だけが、変化する仕組みにして、pthread_join の代わりに while で待つ仕様に変更。
注意点としては、マルチスレッドセーフではないので、タイムアウト時間内に関数をもう一度呼ぶとだめってことくらい (((・ω・)))

これでいちおう動いた。
 

おすすめ

1件の返信

  1. 名無しのPCパーツ より:

    サイトのタイムスタンプ狂ってませんか?
    この記事7月6日の記事ですけど
    日付が6月22日になってますよ
    この記事に限らず3つ前ぐらいから
    日付が6月21日で止まってますし

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です