C言語

libevでechoサーバを作る

パフォーマンスがよいよいと評判のlibevでechoサーバを書いてみる。 echod_libev.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <ev.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #def…</ev.h></errno.h></fcntl.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

libev

http://software.schmorp.de/pkg/libev.html えび経由で。 libevenの改良版?

Windows: 一時ファイルを作成してロックする

_lockingのバイト数がよく分からないなー。 #include <stdio.h> #include <io.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <share.h> #include <sys/locking.h> #include <errno.h> #include <windows.h> #define BUFLEN 1024 int main() { int fd; char ftmp[BUFLEN]; GetTempPathA(sizeof(ftmp), ftmp)…</windows.h></errno.h></sys/locking.h></share.h></sys/stat.h></sys/types.h></fcntl.h></io.h></stdio.h>

WinSockでepollをエミュレートする

細かいところはいい加減。なぜか動いてる。 echoサーバ #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <io.h> #include "wsepoll.h" #include <memory.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define MAX_EVENTS WSA_MAXIMUM_WAIT_EVENTS #define </memory.h></io.h></stdio.h></ws2tcpip.h></winsock2.h>…

LockFileEx

http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpfileio/html/_win32_lockfileex.asp Windwosでflockってどうやるんだろう…と思って、よく分からないのでやっぱりwin32.cを読む。 LockFileExを使うのか、とすぐ分かる。すばらしい。

INFO:種類の Win32 でのファイル I/O

http://support.microsoft.com/kb/99173/ja SOCKETも互換性なし…と。

C ランタイム関数の Win32 で対応する関数一覧

http://support.microsoft.com/default.aspx/kb/99456/ja メモメモ。

WinSockでpollをエミュレート

こんな感じ。 #include <stdio.h> #include <winsock2.h> #include "wspoll.h" #include <memory.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define MAX_NFDS WSA_MAXIMUM_WAIT_EVENTS #define POLL_TIMEOUT 1000 #define die(...) do { fprintf(stderr, __VA_A</memory.h></winsock2.h></stdio.h>…

echod_async.c

Cygwinでは動かず。非同期だからといってIOが多重化されるわけではない…と。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <sys/file.h> #include <signal.h> #include <errno.h> #define ECHO_PORT 7 #define MA…</errno.h></signal.h></sys/file.h></fcntl.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

pollのエミュレートを考え中…

WinSockのイベントまわりのAPIでpoll(2)をエミュレートできないか考え中。 WinSock.hに定義されているかもしれないpollfdと定数はマクロで再定義できそうだし、WSAWaitForMultipleEvents()はイベントの数じゃなくてインデックスを返すけど不要なイベントは無…

pollのエミュレートを考え中… その2

イベントのマッピングはこんな感じかなぁ… poll(3) WinSock POLLIN FD_READ | FD_ACCEPT | FD_CLOSE POLLPRI FD_OOB POLLOUT FD_WRITE | FD_CONNECT | FD_CLOSE POLLRDHUP FD_CLOSE POLLERR × POLLHUP FD_CLOSE POLLNVAL × POLLRDNORM POLLIN POLLRDBAND POL…

EAGAINとWSAEWOULDBLOCK

http://www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/bsd-compatibility.html http://www.koders.com/c/fidECDE0904A9E7E0D9F1AFB22DB9076C356C4C2BCE.aspx?s=map_errno#L183 map_errnoでWSAEWOULDBLOCKをEAGAINにマップするという話はないんだろうか…

echod_winsock_event.c

WSAWaitForMultipleEvents、資料少ない…。動くことは動いたけど、終了処理が怪しいなぁ。 #include <stdio.h> #include <winsock2.h> #define _CRT_SECURE_DEPRECATE_MEMORY #include <memory.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define WSAWFME_TIMEOUT 1000 #define RCVBUFSIZ</memory.h></winsock2.h></stdio.h>…

echod_winsock.c

#include <stdio.h> #include <winsock2.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define die(...) do { fprintf(stderr, __VA_ARGS__); WSACleanup(); exit(1); } while(0) #define debug(...) do { fprintf(stderr, __VA_ARGS__); } while(0) sta</winsock2.h></stdio.h>…

echod_winsock_select.c

fd_setをなめるのがめんどくさいなぁ。 #include <stdio.h> #include <winsock2.h> #include <time.h> #define _CRT_SECURE_DEPRECATE_MEMORY #include <memory.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define die(...) do { fprintf(stderr, __VA_ARGS__); WSAClean</memory.h></time.h></winsock2.h></stdio.h>…

RubyでのWinSockの初期化

拡張でWinSockの初期化をするわけにはいかないよなぁ…ということでRubyのソース(1.8.6-p111)を読んでみる。 win32/win32.cのStartSockets()関数でWinSockで初期化されてた。 static void StartSockets () { WORD version; WSADATA retdata; int ret; #ifndef…

WinSock: WSAPoll

http://msdn2.microsoft.com/en-us/library/ms741669.aspx 最近追加されたみたい。サンプル少ないなー。 Rubyで使ってみようと思ったら、WinSockのバージョンが違って挫折。

echod_winsock_poll.c

書くことは書いたけど、ws2_32.dllのバージョンが古くて動かず。 #include <stdio.h> #include <winsock2.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define MAX_NFDS 64 #define RCVBUFSIZE 256 #define POLL_TIMEOUT 1000 #define die(...) do { fprintf(stderr, __VA_ARGS</winsock2.h></stdio.h>…

echod.c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define die(s) do { perror((s)); exit(1); } while(0) #ifdef DEBUG #…</errno.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

echod_prefork.c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define die(s) do { perror((s)); exit(1); } while(0) #ifdef DEBUG #…</errno.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

echod_multithread.c

TIME_WAITがたまっていくけど、いいのかなぁ・・・ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define die(s) do…</errno.h></pthread.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

echod_select.c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <sys/select.h> #include <sys/time.h> #include <errno.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define die(s) do { f…</errno.h></sys/time.h></sys/select.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

echod_poll.c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <poll.h> #include <errno.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define MAX_NFDS 1024 #define POLL_TIMEOUT 1000 #…</errno.h></poll.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

echod_epoll.c

レベルトリガとして使用。まあ、高速なpoll(2)ですね。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <sys/epoll.h> #include <errno.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define MAX_EV…</errno.h></sys/epoll.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

echod_libevent.c

意外と苦戦。ドキュメントないなー。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <event.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define MAX…</event.h></errno.h></fcntl.h></unistd.h></sys/types.h></arpa/inet.h></sys/socket.h></string.h></stdlib.h></stdio.h>

Poundの振り分けアルゴリズム

Sessionディレクティブでバックエンドの振り分けルールを指定しないときのアルゴリズムが気になったので調べてみる。 svc.c 516行目あたり /* * Find the right back-end for a request */ BACKEND * get_backend(SERVICE *const svc, const struct in_addr …

Poundの振り分けアルゴリズム その2

DynScaleディレクティブを1にセットしておくと、動的に優先度を変えてくれるらしい。 svc.c 1034行目あたり /* * Rescale back-end priorities if needed * runs every 5 minutes */ static void do_rescale(void) { ... sq_average /= n; average /= n; sq_…

Poundの振り分けアルゴリズムをラウンドロビンに変更してみる

すごい適当なパッチ。 設定ファイルで制御するようにすればマシになるかも。 diff -up Pound-2.3.2.orig/config.c Pound-2.3.2/config.c --- Pound-2.3.2.orig/config.c 2007-05-18 17:34:53.000000000 +0900 +++ Pound-2.3.2/config.c 2008-02-11 13:40:41.…

PoundでProxyPassディレクティブみたいなことをやる

requestとheaders[0]を書き換えて「/」を「/local/」にディスパッチ。 つーか、置換やってくれる正規表現ライブラリが欲しいなぁ。 --- http.c.orig 2008-02-11 15:00:11.203125000 +0900 +++ http.c 2008-02-11 15:30:22.859375000 +0900 @@ -436,6 +436,17…

単体と配列とポインタ

http://www.apsis.ch/pound/ 昼休みにPoundのソースを読んでいる。ApacheやRubyに比べると圧倒的にコンパクトかつきれいなコードなので、大変読みやすい(設計の善し悪しは僕には分からない)。それはさておき、svc.cの1375行目あたりにthr_controlというリ…