toge's diary

コンピュータ関連の趣味をつらつらと。

mongoose ほどほど最小サンプル

以前話したmongooseをやっとこさ弄りはじめました。
触っていると分かりますが、小さいけれど必要十分の事ができる素敵ライブラリです。

で、公式のソースだとmain.cは色々やりすぎだし、test/embed.cは色々はしょりすぎなので、中庸的なソースコードを作ってみました。

基本はmain.cですが、C++で書いちゃったのと、引数や設定ファイルでの設定変更部分は本質的ではないので削除しちゃいました。

#include <cstdio>
#include <cstdlib>
#include <csignal>

#include "mongoose.h"

#ifdef _WIN32
#  include <windows.h>
#  include <winsvc.h>
#  define sleep(x) Sleep((x) * 1000)
#else
#  include <sys/wait.h>
#  include <unistd.h>
#endif /* _WIN32 */

static int exit_flag;

static void
signal_handler(int sig_num)
{
#ifndef _WIN32
  if (sig_num == SIGCHLD)
  {
    while (waitpid(-1, &sig_num, WNOHANG) > 0)
    {}
  }
  else
#endif /* _WIN32 */
  {
    exit_flag = sig_num;
  }
}

int
main(int argc, char *argv[])
{
  // シグナルハンドラの設定
#ifndef _WIN32
  signal(SIGCHLD, signal_handler);
#endif
  signal(SIGTERM, signal_handler);
  signal(SIGINT, signal_handler);

  // mongooseの初期化
  mg_context *ctx = mg_start();
  if (ctx == NULL)
  {
    exit(EXIT_FAILURE);
  }

  // mongooseの設定
  if (mg_set_option(ctx, "ports", "8081") != 1)
  {
    exit(EXIT_FAILURE);
  }

  while (exit_flag == 0)
  {
    sleep(1);
  }

  printf("Exiting on signal %d, "
         "waiting for all threads to finish...", exit_flag);
  fflush(stdout);

  // mongooseの終了
  mg_stop(ctx);

  puts("done.");

  return (EXIT_SUCCESS);
}

mg_start()とmg_set_option()の実行順序は逆な気がしましたが、ソースを見るとmg_set_optionでポートを指定したタイミングで呼び出される関数があり、その関数内でポートのbindをしていることが分かりました。

・・・逆に言えばmg_start()してからじゃないとmg_set_option()できないってこと?

設定項目変更時のコールバック関数っていうのは確かにいいですな。何か作るときに考えておこう。