Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <000e01c1c40f$a18c13f0$0610a8c0@wyw> From: "Wu Yongwei" To: Subject: Long duration of close(socket) and signal problem Date: Tue, 5 Mar 2002 14:29:07 +0800 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0007_01C1C452.1C169950" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4807.1700 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300 ------=_NextPart_000_0007_01C1C452.1C169950 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit To compare the network performance of Cygwin and native WinSock, I wrote the attached code. Under the three compiler (MinGW 1.1 GCC 2.95, Cygwin GCC 2.95, GCC 2.96 of Red Hat 7.1) I used, I typed only "gcc -Wall fakeweb.c -o fakeweb" to build. Then I used a Web stress tool to send HTTP GET requests repeatedly (like ApacheBench, try "ab -n 100 -c 1 x.x.x.x/" on a Linux box). To my great surprise, the close(socket) operation took EXTREMELY long. It took 0.11 second (CPU usage was low), while this operation under MinGW 1.1 on the same machine took only 0.00019 second. On another Linux machine, close took 0.000043 second. Another problem concerns signal handling. This program could be stopped by CTRL-C under MinGW and Linux, but it hung and used 100% of CPU under Cygwin when CTRL-C was hit. Any help? Best regards, Wu Yongwei P.S. On a last test, one strange thing happened. If I reload 127.0.0.1 in a local browser quickly while running fakeweb, the displayed close time is much smaller. It does not work on a remote browser. Just wrote it here and does not expect an explanation for this point. ------=_NextPart_000_0007_01C1C452.1C169950 Content-Type: application/octet-stream; name="fakeweb.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="fakeweb.c" #include #include #include #include #ifdef _WIN32 #include #else #include #include #include #include #define closesocket close #define SOCKET int #define INVALID_SOCKET (-1) #define SOCKET_ERROR (-1) #endif #include "pctimer.h" char response[] =3D "\r\n" "\r\n" "A Test Page\r\n" "\r\n" "\r\n" "

Hello, this is the FakeWeb-produced page.\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "

Blablablablablablablablabla\r\n" "\r\n" "\r\n"; pctimer_t ta, tr, ts, tc; int i; SOCKET ACCEPT(SOCKET s, struct sockaddr *addr, int *addrlen) { static int first =3D 1; pctimer_t t; SOCKET r; t =3D pctimer(); r =3D accept(s, addr, addrlen); if (first) first =3D 0; else ta +=3D pctimer() - t; return r; } int RECV(SOCKET s, char *buf, int len, int flags) { pctimer_t t; int r; t =3D pctimer(); r =3D recv(s, buf, len, flags); tr +=3D pctimer() - t; return r; } int SEND(SOCKET s, const char *buf, int len, int flags) { pctimer_t t; int r; t =3D pctimer(); r =3D send(s, buf, len, flags); ts +=3D pctimer() - t; return r; } int CLOSESOCKET(SOCKET s) { pctimer_t t; int r; t =3D pctimer(); r =3D closesocket(s); tc +=3D pctimer() - t; return r; } void PrintResult(int sig) { if (i) { printf("%d\n", i); printf("accept: %f\n", ta / i); printf("recv: %f\n", tr / i); printf("send: %f\n", ts / i); printf("close: %f\n", tc / i); } exit(0); } int main() { SOCKET listenfd, connfd; struct sockaddr_in servaddr; char buf[4096]; int nReceived; #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested =3D MAKEWORD(2, 0); if (WSAStartup(wVersionRequested, &wsaData)) { printf("WSAStartup error\n"); exit(1); } #endif listenfd =3D socket(AF_INET, SOCK_STREAM, 0); if (listenfd =3D=3D INVALID_SOCKET) { printf("Socket error\n"); exit(1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family =3D AF_INET; servaddr.sin_addr.s_addr =3D htonl(INADDR_ANY); servaddr.sin_port =3D htons(80); if (bind(listenfd, (void *)&servaddr, sizeof(servaddr)) =3D=3D = SOCKET_ERROR) { printf("Cannot bind port 80\n"); exit(1); } if (listen(listenfd, 1) =3D=3D SOCKET_ERROR) { printf("Cannot listen on port 80\n"); exit(1); } signal(SIGINT, PrintResult); for (i =3D 0; i < 1; i++) { connfd =3D ACCEPT(listenfd, NULL, NULL); do { nReceived =3D RECV(connfd, buf, sizeof buf, 0); } while (nReceived && nReceived !=3D SOCKET_ERROR && = buf[nReceived - 1] !=3D '\n'); #ifdef _WIN32 if (nReceived =3D=3D SOCKET_ERROR) printf("WinSock Error: %d\n", WSAGetLastError()); #else if (nReceived =3D=3D SOCKET_ERROR) printf("Socket Error: %d\n", errno); #endif sprintf(buf, "HTTP/1.0 200 OK\r\n" "Content-Length: %d\r\n" "Content-Type: text/html\r\n" "\r\n%s", sizeof response - 1, response); SEND(connfd, buf, strlen(buf), 0); CLOSESOCKET(connfd); } #ifdef _WIN32 WSACleanup(); #endif PrintResult(0); return 0; } ------=_NextPart_000_0007_01C1C452.1C169950 Content-Type: application/octet-stream; name="pctimer.h" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pctimer.h" /* * pctimer.h 1.1 02/03/05 * * Uses Win32 performance counter functions to get a high-resolution timer * * By Wu Yongwei * */ #ifndef _PCTIMER_H typedef double pctimer_t; #if defined(_WIN32) || defined(__CYGWIN__) #ifndef _WIN32 #define PCTIMER_NO_WIN32 #endif /* _WIN32 */ #define WIN32_LEAN_AND_MEAN #include #ifdef PCTIMER_NO_WIN32 #undef PCTIMER_NO_WIN32 #undef _WIN32 #endif /* PCTIMER_NO_WIN32 */ __inline pctimer_t pctimer() { static LARGE_INTEGER pcount, pcfreq; static int initflag; if (!initflag) { QueryPerformanceFrequency(&pcfreq); initflag++; } QueryPerformanceCounter(&pcount); return (double)pcount.QuadPart / (double)pcfreq.QuadPart; } #else /* Win32/Cygwin */ #include __inline pctimer_t pctimer() { struct timeval tv; gettimeofday(&tv, NULL); return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; } #endif /* Win32/Cygwin */ #endif /* _PCTIMER_H */ ------=_NextPart_000_0007_01C1C452.1C169950 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ------=_NextPart_000_0007_01C1C452.1C169950--