head 1.57; access; symbols PTH_2_0_7:1.56 PTH_2_0_6:1.55 PTH_2_0_5:1.55 PTH_2_0_4:1.55 PTH_2_0_3:1.54 PTH_2_0_2:1.54 PTH_2_0_1:1.54 PTH_2_0_0:1.53 PTH_2_0b2:1.52 PTH_2_0b1:1.52 PTH_2_0b0:1.52 PTH_1_4:1.52.0.2 PTH_1_4_1:1.52 PTH_1_4_0:1.51 PTH_1_3_7:1.50 PTH_1_4a3:1.50 PTH_1_3_6:1.50 PTH_1_4a2:1.50 PTH_1_3_5:1.50 PTH_1_4a1:1.50 PTH_1_3_4:1.50 PTH_1_3:1.50.0.2 PTH_1_3_3:1.50 PTH_1_3_2:1.49 PTH_1_3_1:1.49 PTH_1_3_0:1.49 PTH_1_3b3:1.48 PTH_1_2_3:1.43.2.2 PTH_1_3b2:1.48 PTH_1_3b1:1.48 PTH_1_3a5:1.48 PTH_1_3a4:1.47 PTH_1_3a3:1.47 PTH_1_2_2:1.43.2.1 PTH_1_3a2:1.47 PTH_1_2_1:1.43.2.1 PTH_1_3a1:1.45 PTH_1_2:1.43.0.2 PTH_1_2_0:1.43 PTH_1_2b8:1.42 PTH_1_2b7:1.42 PTH_1_1_6:1.39.2.1 PTH_1_2b6:1.42 PTH_1_2b5:1.42 PTH_1_2b4:1.42 PTH_1_2b3:1.41 PTH_1_2b2:1.40 PTH_1_2b1:1.40 PTH_1_1_5:1.39 PTH_1_0_6:1.35 PTH_1_0_5:1.35 PTH_1_0:1.35.0.2 PTH_1_1:1.39.0.2 PTH_1_1_4:1.39 PTH_1_1_3:1.39 PTH_1_1_2:1.38 PTH_1_1_1:1.38 PTH_1_1_0:1.38 PTH_1_1b7:1.38 PTH_1_1b6:1.38 PTH_1_1b5:1.38 PTH_1_1b4:1.37 PTH_1_1b3:1.37 PTH_1_1b2:1.37 PTH_1_1b1:1.37 PTH_1_0_4:1.35 PTH_1_0_3:1.35 PTH_1_0_2:1.35 PTH_1_0_1:1.35 PTH_1_0_0:1.34 PTH_1_0b8:1.34 PTH_1_0b7:1.34 PTH_1_0b6:1.34 PTH_1_0b5:1.34 PTH_1_0b4:1.32 PTH_1_0b3:1.30 PTH_1_0b2:1.30 PTH_1_0b1:1.29 PTH_0_9_21:1.28 PTH_0_9_20:1.28 PTH_0_9_19:1.27 PTH_0_9_18:1.27 PTH_0_9_17:1.26 PTH_0_9_16:1.26 PTH_0_9_15:1.26 PTH_0_9_14:1.26 PTH_0_9_13:1.25 PTH_0_9_12:1.23 PTH_0_9_11:1.22 PTH_0_9_10:1.21 PTH_0_9_9:1.21 PTH_0_9_8:1.20 PTH_0_9_7:1.15 PTH_0_9_6:1.12 PTH_0_9_5:1.10 PTH_0_9_4:1.10 PTH_0_9_3:1.10 PTH_0_9_2:1.5 PTH_0_9_1:1.2 PTH_0_9_0:1.1.1.1 RSE:1.1.1; locks; strict; comment @ * @; 1.57 date 2007.01.01.18.23.53; author rse; state Exp; branches; next 1.56; commitid 9DhdiirNzQPBIP0s; 1.56 date 2006.06.08.17.54.54; author rse; state Exp; branches; next 1.55; commitid x8N3mLVdQgkbdeAr; 1.55 date 2004.12.31.19.34.45; author rse; state Exp; branches; next 1.54; 1.54 date 2004.07.13.10.50.49; author rse; state Exp; branches; next 1.53; 1.53 date 2003.01.01.15.49.12; author rse; state Exp; branches; next 1.52; 1.52 date 2002.01.27.11.03.41; author rse; state Exp; branches; next 1.51; 1.51 date 2001.03.24.14.51.05; author rse; state Exp; branches; next 1.50; 1.50 date 2000.03.03.15.42.10; author rse; state Exp; branches; next 1.49; 1.49 date 2000.02.19.16.08.11; author rse; state Exp; branches; next 1.48; 1.48 date 2000.01.09.16.31.45; author rse; state Exp; branches; next 1.47; 1.47 date 99.12.30.21.59.01; author rse; state Exp; branches; next 1.46; 1.46 date 99.11.09.08.11.32; author rse; state Exp; branches; next 1.45; 1.45 date 99.11.01.19.03.49; author rse; state Exp; branches; next 1.44; 1.44 date 99.11.01.10.27.21; author rse; state Exp; branches; next 1.43; 1.43 date 99.10.31.11.46.14; author rse; state Exp; branches 1.43.2.1; next 1.42; 1.42 date 99.09.17.16.29.33; author rse; state Exp; branches; next 1.41; 1.41 date 99.09.17.08.01.56; author rse; state Exp; branches; next 1.40; 1.40 date 99.09.01.11.22.56; author rse; state Exp; branches; next 1.39; 1.39 date 99.08.27.14.52.48; author rse; state Exp; branches 1.39.2.1; next 1.38; 1.38 date 99.08.15.15.20.35; author rse; state Exp; branches; next 1.37; 1.37 date 99.08.03.15.05.51; author rse; state Exp; branches; next 1.36; 1.36 date 99.08.03.12.24.03; author rse; state Exp; branches; next 1.35; 1.35 date 99.07.19.06.45.01; author rse; state Exp; branches 1.35.2.1; next 1.34; 1.34 date 99.07.10.15.23.31; author rse; state Exp; branches; next 1.33; 1.33 date 99.07.10.14.21.18; author rse; state Exp; branches; next 1.32; 1.32 date 99.07.08.10.34.02; author rse; state Exp; branches; next 1.31; 1.31 date 99.07.08.10.19.12; author rse; state Exp; branches; next 1.30; 1.30 date 99.07.04.12.05.36; author rse; state Exp; branches; next 1.29; 1.29 date 99.06.27.15.38.04; author rse; state Exp; branches; next 1.28; 1.28 date 99.06.24.10.54.29; author rse; state Exp; branches; next 1.27; 1.27 date 99.06.20.09.52.02; author rse; state Exp; branches; next 1.26; 1.26 date 99.06.01.14.36.33; author rse; state Exp; branches; next 1.25; 1.25 date 99.06.01.09.55.27; author rse; state Exp; branches; next 1.24; 1.24 date 99.05.31.12.43.00; author rse; state Exp; branches; next 1.23; 1.23 date 99.05.30.09.29.20; author rse; state Exp; branches; next 1.22; 1.22 date 99.05.28.11.24.12; author rse; state Exp; branches; next 1.21; 1.21 date 99.05.25.10.53.08; author rse; state Exp; branches; next 1.20; 1.20 date 99.05.24.12.06.50; author rse; state Exp; branches; next 1.19; 1.19 date 99.05.24.11.45.15; author rse; state Exp; branches; next 1.18; 1.18 date 99.05.24.10.07.45; author rse; state Exp; branches; next 1.17; 1.17 date 99.05.24.07.58.13; author rse; state Exp; branches; next 1.16; 1.16 date 99.05.24.07.28.00; author rse; state Exp; branches; next 1.15; 1.15 date 99.05.23.14.32.54; author rse; state Exp; branches; next 1.14; 1.14 date 99.05.23.14.11.53; author rse; state Exp; branches; next 1.13; 1.13 date 99.05.23.14.08.41; author rse; state Exp; branches; next 1.12; 1.12 date 99.05.22.14.37.53; author rse; state Exp; branches; next 1.11; 1.11 date 99.05.22.12.28.30; author rse; state Exp; branches; next 1.10; 1.10 date 99.05.14.20.19.24; author rse; state Exp; branches; next 1.9; 1.9 date 99.05.14.19.58.15; author rse; state Exp; branches; next 1.8; 1.8 date 99.05.14.19.45.05; author rse; state Exp; branches; next 1.7; 1.7 date 99.05.14.19.44.07; author rse; state Exp; branches; next 1.6; 1.6 date 99.05.14.19.33.37; author rse; state Exp; branches; next 1.5; 1.5 date 99.05.14.15.05.05; author rse; state Exp; branches; next 1.4; 1.4 date 99.05.14.15.03.33; author rse; state Exp; branches; next 1.3; 1.3 date 99.05.14.09.40.05; author rse; state Exp; branches; next 1.2; 1.2 date 99.05.13.16.36.57; author rse; state Exp; branches; next 1.1; 1.1 date 99.05.13.12.18.16; author rse; state Exp; branches 1.1.1.1; next ; 1.43.2.1 date 99.11.01.10.25.02; author rse; state Exp; branches; next 1.43.2.2; 1.43.2.2 date 2000.02.04.22.07.18; author rse; state Exp; branches; next ; 1.39.2.1 date 99.09.24.21.52.52; author rse; state Exp; branches; next ; 1.35.2.1 date 99.08.31.08.33.56; author rse; state Exp; branches; next ; 1.1.1.1 date 99.05.13.12.18.16; author rse; state Exp; branches; next ; desc @@ 1.57 log @Adjusted all copyright messages for new year 2007. @ text @/* ** GNU Pth - The GNU Portable Threads ** Copyright (c) 1999-2007 Ralf S. Engelschall ** ** This file is part of GNU Pth, a non-preemptive thread scheduling ** library which can be found at http://www.gnu.org/software/pth/. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation; either ** version 2.1 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ** USA, or contact Ralf S. Engelschall . ** ** test_httpd.c: Pth test program (faked HTTP daemon) */ /* ``Unix is simple. It just takes a genius to understand its simplicity.'' --- Dennis Ritchie */ #include #include #include #include #include #include #include #include #include #include #include #include #include "pth.h" #include "test_common.h" /* * The HTTP request handler */ #define MAXREQLINE 1024 static void *handler(void *_arg) { int fd = (int)((long)_arg); char caLine[MAXREQLINE]; char str[1024]; int n; /* read request */ for (;;) { n = pth_readline(fd, caLine, MAXREQLINE); if (n < 0) { fprintf(stderr, "read error: errno=%d\n", errno); close(fd); return NULL; } if (n == 0) break; if (n == 1 && caLine[0] == '\n') break; caLine[n-1] = NUL; } /* simulate a little bit of processing ;) */ pth_yield(NULL); /* generate response */ sprintf(str, "HTTP/1.0 200 Ok\r\n" "Server: test_httpd/%x\r\n" "Connection: close\r\n" "Content-type: text/plain\r\n" "\r\n" "Just a trivial test for GNU Pth\n" "to show that it's serving data.\r\n", PTH_VERSION); pth_write(fd, str, strlen(str)); /* close connection and let thread die */ fprintf(stderr, "connection shutdown (fd: %d)\n", fd); close(fd); return NULL; } /* * A useless ticker we let run just for fun in parallel */ static void *ticker(void *_arg) { time_t now; char *ct; float avload; for (;;) { pth_sleep(5); now = time(NULL); ct = ctime(&now); ct[strlen(ct)-1] = NUL; pth_ctrl(PTH_CTRL_GETAVLOAD, &avload); fprintf(stderr, "ticker woken up on %s, average load: %.2f\n", ct, avload); } /* NOTREACHED */ return NULL; } /* * And the server main procedure */ #if defined(FD_SETSIZE) #define REQ_MAX FD_SETSIZE-100 #else #define REQ_MAX 100 #endif static int s; pth_attr_t attr; static void myexit(int sig) { close(s); pth_attr_destroy(attr); pth_kill(); fprintf(stderr, "**Break\n"); exit(0); } int main(int argc, char *argv[]) { struct sockaddr_in sar; struct protoent *pe; struct sockaddr_in peer_addr; socklen_t peer_len; int sr; int port; /* initialize scheduler */ pth_init(); signal(SIGPIPE, SIG_IGN); signal(SIGINT, myexit); signal(SIGTERM, myexit); /* argument line parsing */ if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } port = atoi(argv[1]); if (port <= 0 || port >= 65535) { fprintf(stderr, "Illegal port: %d\n", port); exit(1); } fprintf(stderr, "This is TEST_HTTPD, a Pth test using socket I/O.\n"); fprintf(stderr, "\n"); fprintf(stderr, "Multiple connections are accepted on the specified port.\n"); fprintf(stderr, "For each connection a separate thread is spawned which\n"); fprintf(stderr, "reads a HTTP request the socket and writes back a constant\n"); fprintf(stderr, "(and useless) HTTP response to the socket.\n"); fprintf(stderr, "Additionally a useless ticker thread awakens every 5s.\n"); fprintf(stderr, "Watch the average scheduler load the ticker displays.\n"); fprintf(stderr, "Hit CTRL-C for stopping this test.\n"); fprintf(stderr, "\n"); /* run a just for fun ticker thread */ attr = pth_attr_new(); pth_attr_set(attr, PTH_ATTR_NAME, "ticker"); pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE); pth_attr_set(attr, PTH_ATTR_STACK_SIZE, 64*1024); pth_spawn(attr, ticker, NULL); /* create TCP socket */ if ((pe = getprotobyname("tcp")) == NULL) { perror("getprotobyname"); exit(1); } if ((s = socket(AF_INET, SOCK_STREAM, pe->p_proto)) == -1) { perror("socket"); exit(1); } /* bind socket to port */ sar.sin_family = AF_INET; sar.sin_addr.s_addr = INADDR_ANY; sar.sin_port = htons(port); if (bind(s, (struct sockaddr *)&sar, sizeof(struct sockaddr_in)) == -1) { perror("socket"); exit(1); } /* start listening on the socket with a queue of 10 */ if (listen(s, REQ_MAX) == -1) { perror("listen"); exit(1); } /* finally loop for requests */ pth_attr_set(attr, PTH_ATTR_NAME, "handler"); fprintf(stderr, "listening on port %d (max %d simultaneous connections)\n", port, REQ_MAX); for (;;) { /* accept next connection */ peer_len = sizeof(peer_addr); if ((sr = pth_accept(s, (struct sockaddr *)&peer_addr, &peer_len)) == -1) { perror("accept"); pth_sleep(1); continue; } if (pth_ctrl(PTH_CTRL_GETTHREADS) >= REQ_MAX) { fprintf(stderr, "currently no more connections acceptable\n"); continue; } fprintf(stderr, "connection established (fd: %d, ip: %s, port: %d)\n", sr, inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port)); /* spawn new handling thread for connection */ pth_spawn(attr, handler, (void *)((long)sr)); } } @ 1.56 log @Adjusted all copyright messages for new year 2006 @ text @d3 1 a3 1 ** Copyright (c) 1999-2006 Ralf S. Engelschall @ 1.55 log @Adjusted all copyright messages for new year 2005. @ text @d3 1 a3 1 ** Copyright (c) 1999-2005 Ralf S. Engelschall @ 1.54 log @Adjusted all copyright messages for new year 2004. @ text @d3 1 a3 1 ** Copyright (c) 1999-2004 Ralf S. Engelschall @ 1.53 log @Adjusted all copyright messages for new year 2003. @ text @d3 1 a3 1 ** Copyright (c) 1999-2003 Ralf S. Engelschall @ 1.52 log @bump copyright year @ text @d3 1 a3 1 ** Copyright (c) 1999-2002 Ralf S. Engelschall @ 1.51 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2001 Ralf S. Engelschall @ 1.50 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2000 Ralf S. Engelschall @ 1.49 log @*** empty log message *** @ text @d179 1 a179 1 pth_attr_set(attr, PTH_ATTR_STACK_SIZE, 32*1024); @ 1.48 log @*** empty log message *** @ text @d112 1 a112 1 /* NOT REACHED */ @ 1.47 log @*** empty log message *** @ text @d132 1 a133 1 pth_attr_destroy(attr); @ 1.46 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999 Ralf S. Engelschall @ 1.45 log @*** empty log message *** @ text @d25 1 a25 1 /* ``Unix is simple. It just takes a d79 1 a79 1 "Server: test_httpd/%x\r\n" d84 1 a84 1 "to show that it's serving data.\r\n", PTH_VERSION); d109 1 a109 1 fprintf(stderr, "ticker woken up on %s, average load: %.2f\n", d138 1 a138 1 int main(int argc, char *argv[]) d222 1 a222 1 fprintf(stderr, "connection established (fd: %d, ip: %s, port: %d)\n", @ 1.44 log @*** empty log message *** @ text @d25 3 @ 1.43 log @*** empty log message *** @ text @d2 1 a2 2 ** test_httpd.c -- Pth test program (faked HTTP daemon) ** d22 2 @ 1.43.2.1 log @*** empty log message *** @ text @d2 2 a3 1 ** GNU Pth - The GNU Portable Threads a22 2 ** ** test_httpd.c: Pth test program (faked HTTP daemon) @ 1.43.2.2 log @*** empty log message *** @ text @d129 1 a130 1 pth_kill(); @ 1.42 log @*** empty log message *** @ text @d12 1 a12 1 ** version 2 of the License, or (at your option) any later version. @ 1.41 log @*** empty log message *** @ text @d155 1 a155 1 if (port <= 0 || port >= 65553) { @ 1.40 log @*** empty log message *** @ text @d10 1 a10 1 ** modify it under the terms of the GNU Library General Public d17 1 a17 1 ** Library General Public License for more details. d19 1 a19 1 ** You should have received a copy of the GNU Library General Public @ 1.39 log @*** empty log message *** @ text @d139 1 a139 1 int peer_len; d208 1 a208 1 peer_len = sizeof (peer_addr); @ 1.39.2.1 log @*** empty log message *** @ text @d155 1 a155 1 if (port <= 0 || port >= 65535) { @ 1.38 log @*** empty log message *** @ text @d175 1 a175 1 pth_attr_set(attr, PTH_ATTR_STACK_SIZE, 32*16384); @ 1.37 log @*** empty log message *** @ text @d59 1 a59 1 fprintf(stderr, "read error: (%d) %s\n", errno, strerror(errno)); @ 1.36 log @*** empty log message *** @ text @d59 1 a59 1 fprintf(stderr, "read error"); @ 1.35 log @*** empty log message *** @ text @a54 3 /* switch socket to non-blocking I/O mode */ pth_nonblocking(fd); d80 1 a80 1 "to show that's serving data.\r\n", PTH_VERSION); a186 3 /* switch socket to non-blocking I/O mode */ pth_nonblocking(s); @ 1.35.2.1 log @*** empty log message *** @ text @d178 1 a178 1 pth_attr_set(attr, PTH_ATTR_STACK_SIZE, 32*1024); @ 1.34 log @*** empty log message *** @ text @d40 2 @ 1.33 log @*** empty log message *** @ text @d80 1 a80 1 "Just a trivial test for PTH\n" @ 1.32 log @*** empty log message *** @ text @d144 6 a170 6 /* initialize scheduler */ pth_init(); signal(SIGPIPE, SIG_IGN); signal(SIGINT, myexit); signal(SIGTERM, myexit); @ 1.31 log @*** empty log message *** @ text @d2 1 a2 1 ** test_httpd.c -- PTH test program (faked HTTP daemon) d155 1 a155 1 fprintf(stderr, "This is TEST_HTTPD, a PTH test using socket I/O.\n"); @ 1.30 log @*** empty log message *** @ text @d6 2 a7 2 ** This file is part of PTH, a non-preemptive thread scheduling library ** which can be found at http://www.gnu.org/software/pth/. @ 1.29 log @*** empty log message *** @ text @d7 1 a7 1 ** which can be found at http://www.engelschall.com/sw/pth/. @ 1.28 log @*** empty log message *** @ text @d124 1 d130 1 a136 1 pth_attr_t attr; d173 5 a177 2 attr = pth_attr("ticker", PTH_PRIO_STD, PTH_FLAG_NOJOIN, PTH_CANCEL_DEFAULT, 32*1024, NULL); pth_spawn(&attr, ticker, NULL); d208 1 a208 1 attr = pth_attr("handler", PTH_PRIO_STD, PTH_FLAG_NOJOIN, PTH_CANCEL_DEFAULT, 32*1024, NULL); d226 1 a226 1 pth_spawn(&attr, handler, (void *)((long)sr)); @ 1.27 log @*** empty log message *** @ text @d72 1 a72 1 pth_yield(); @ 1.26 log @*** empty log message *** @ text @d172 1 a172 1 attr = pth_attr("ticker", PTH_PRIO_STD, PTH_FLAG_NOJOIN, 32*1024, NULL); d204 1 a204 1 attr = pth_attr("handler", PTH_PRIO_STD, PTH_FLAG_NOJOIN, 32*1024, NULL); @ 1.25 log @*** empty log message *** @ text @d68 1 a68 1 caLine[n-1] = '\0'; d104 1 a104 1 ct[strlen(ct)-1] = '\0'; @ 1.24 log @*** empty log message *** @ text @d20 1 a20 1 ** License along with this library; if not, write to the Free @ 1.23 log @*** empty log message *** @ text @d172 1 a172 1 attr = pth_attr("ticker", PTH_PRIO_STD, PTH_FLAG_NOJOIN, 32*1024); d204 1 a204 1 attr = pth_attr("handler", PTH_PRIO_STD, PTH_FLAG_NOJOIN, 32*1024); @ 1.22 log @*** empty log message *** @ text @d76 1 a76 1 "Server: test_httpd/%d\r\n" a135 2 pth_t req_thread[REQ_MAX]; int req_socket[REQ_MAX]; d140 1 a140 1 int req_num; a205 1 req_num = 0; d208 2 a209 2 if ((req_socket[req_num] = pth_accept(s, (struct sockaddr *)&peer_addr, &peer_len)) == -1) { d214 1 a214 1 if (req_num >= REQ_MAX) { d219 1 a219 1 req_socket[req_num], inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port)); d222 1 a222 1 req_thread[req_num] = pth_spawn(&attr, handler, (void *)((long)req_socket[req_num])); @ 1.21 log @*** empty log message *** @ text @d48 1 a48 1 int fd = (int)_arg; d225 1 a225 1 req_thread[req_num] = pth_spawn(&attr, handler, (void *)req_socket[req_num]); @ 1.20 log @*** empty log message *** @ text @d174 1 a174 1 attr = pth_attr("ticker", PTH_PRIO_STD, PTH_FLAG_NONE, 32*1024); d206 1 a206 1 attr = pth_attr("handler", PTH_PRIO_STD, PTH_FLAG_NONE, 32*1024); @ 1.19 log @*** empty log message *** @ text @d29 1 @ 1.18 log @*** empty log message *** @ text @d27 1 d99 1 a99 1 while (1) { d108 2 @ 1.17 log @*** empty log message *** @ text @d170 1 a170 1 attr = pth_attr("ticker", 0, 0, 32*1024, FALSE); d202 1 a202 1 attr = pth_attr("handler", 0, 0, 32*1024, FALSE); @ 1.16 log @*** empty log message *** @ text @d6 1 a6 1 ** This file is part of PTH, a non-preemtive thread scheduling library @ 1.15 log @*** empty log message *** @ text @d96 1 d103 1 d105 1 a105 1 ct, pth_load()); d121 1 a121 1 void myexit(int sig) @ 1.14 log @*** empty log message *** @ text @d83 1 a83 1 fprintf(stderr, "test_httpd: connection shutdown (fd: %d)\n", fd); d102 1 a102 1 fprintf(stderr, "test_httpd: ticker woken up on %s, average load: %.2f\n", d117 10 a135 1 int s; d150 11 d164 2 d201 1 a201 1 fprintf(stderr, "test_httpd: listening on port %d (max %d simultaneous connections)\n", port, REQ_MAX); d212 1 a212 1 fprintf(stderr, "parent: currently no more connections acceptable\n"); d215 1 a215 1 fprintf(stderr, "test_httpd: connection established (fd: %d, ip: %s, port: %d)\n", a221 3 /* kill scheduler */ pth_kill(); exit(0); @ 1.13 log @*** empty log message *** @ text @d103 1 a103 1 ct, pth_averageload()); @ 1.12 log @*** empty log message *** @ text @d95 2 d98 1 a98 1 pth_sleep(10); d100 4 a103 1 fprintf(stderr, "test_httpd: ticker was woken up on %s", ctime(&now)); d186 1 @ 1.11 log @*** empty log message *** @ text @d2 21 a22 2 ** test_httpd -- faked HTTP server for testing purposes ** Copyright (c) 1999 Ralf S. Engelschall, All Rights Reserved. @ 1.10 log @*** empty log message *** @ text @d50 3 d122 1 a122 1 attr = pth_attr("ticker", 0, 0, 8*1024, FALSE); d154 1 a154 1 attr = pth_attr("handler", 0, 0, 8*1024, FALSE); @ 1.9 log @*** empty log message *** @ text @d25 1 a25 1 static void *req_handler(void *_arg) a31 2 /* fprintf(stderr, "child: [%03d] started\n", fd); */ a35 1 /* fprintf(stderr, "child: [%03d] recv: HTTP request\n", fd); */ a50 1 /* fprintf(stderr, "child: [%03d] send: trivial HTTP response\n", fd); */ d52 1 a52 1 "Server: pth_test2\r\n" d57 1 a57 1 "to show that's serving data.\r\n"); d61 1 a62 1 /* fprintf(stderr, "child: [%03d] terminated\n", fd); */ d84 3 d88 1 d118 3 a120 2 /* pre-configure some thread attributes */ attr = pth_attr("request job", 0, 0, 8*1024, FALSE); d151 2 a152 1 fprintf(stderr, "test_httpd: listening on port %d\n", port); a153 1 pth_spawn(PTH_DEFATTR, ticker, NULL); d162 1 a162 1 fprintf(stderr, "parent: no more connections acceptable\n"); d165 1 a165 1 fprintf(stderr, "test_httpd: incoming connection (fd: %d, ip: %s, port: %d)\n", d169 1 a169 1 req_thread[req_num] = pth_spawn(&attr, req_handler, (void *)req_socket[req_num]); @ 1.8 log @*** empty log message *** @ text @d32 1 a32 1 fprintf(stderr, "child: [%03d] started\n", fd); d38 1 a38 1 fprintf(stderr, "child: [%03d] recv: HTTP request\n", fd); d54 1 a54 1 fprintf(stderr, "child: [%03d] send: trivial HTTP response\n", fd); d66 1 a66 1 fprintf(stderr, "child: [%03d] terminated\n", fd); d80 1 a80 1 fprintf(stderr, "ticker: woken up on %s", ctime(&now)); d144 1 a144 1 if (listen(s, 10) == 1) { d150 1 a150 1 fprintf(stderr, "Listening on port %d\n", port); d164 1 a164 1 fprintf(stderr, "parent: connection accepted [%03d] (IP: %s, port %d)\n", @ 1.7 log @*** empty log message *** @ text @d20 1 a20 1 * Now the fakes HTTP request handler @ 1.6 log @*** empty log message *** @ text @d20 1 a20 3 * implementation of a greedy tread-safe readline function to avoid slow * byte-wise reading from the sockets (which is important for * high-performance) d23 1 a23 81 #define READLINE_MAXLEN 1024 static pth_key_t readline_key; static pth_once_t readline_once_var = PTH_ONCE_INIT; typedef struct { int rl_cnt; char *rl_bufptr; char rl_buf[READLINE_MAXLEN]; } readline_t; static ssize_t readline_read(readline_t *rl, int fd, char *ptr) { if (rl->rl_cnt <= 0) { for (;;) { if ((rl->rl_cnt = pth_read(fd, rl->rl_buf, READLINE_MAXLEN)) < 0) { if (errno == EINTR) continue; return -1; } else if (rl->rl_cnt == 0) return 0; rl->rl_bufptr = rl->rl_buf; break; } } rl->rl_cnt--; *ptr = *rl->rl_bufptr++; return 1; } static void readline_destructor(void *vp) { free(vp); return; } static void readline_once(void *vp) { pth_key_create(&readline_key, readline_destructor); return; } static ssize_t my_readline(int fd, void *vp, size_t maxlen) { int n, rc; char c, *cp; readline_t *rl; pth_once(&readline_once_var, readline_once, NULL); if ((rl = pth_getspecific(readline_key)) == NULL) { rl = calloc(1, sizeof(readline_t)); pth_setspecific(readline_key, rl); } cp = vp; for (n = 1; n < maxlen; n++) { if ((rc = readline_read(rl, fd, &c)) == 1) { if (c == '\r') { n--; continue; } *cp++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return 0; else break; } else return -1; } *cp = '\0'; return n; } /* * Now the fakes HTTP request handler */ d28 1 a28 1 char caLine[1024]; d40 1 a40 1 n = my_readline(fd, caLine, 1024); @ 1.5 log @*** empty log message *** @ text @d27 3 d56 12 d74 2 a75 1 if ((rl = pth_retrieve(pth_self())) == NULL) { d77 1 a77 1 pth_store(pth_self(), rl, NULL); @ 1.4 log @*** empty log message *** @ text @d1 4 @ 1.3 log @*** empty log message *** @ text @d4 1 d8 1 d15 15 a29 1 static void *ticker(void *_arg) d31 12 a42 5 time_t now; while (1) { pth_sleep(10); now = time(NULL); fprintf(stderr, "ticker: woken up on %s", ctime(&now)); d44 3 d49 1 a49 1 static int req_readline(int fd, char *buf, int len) d51 27 a77 13 int n; int p; p = 0; while (1) { n = pth_read(fd, &buf[p], 1); if (n <= 0) break; if (buf[p] == '\r') continue; if (buf[p] == '\n') break; p++; d79 2 a80 1 return p; d83 4 d102 1 a102 1 n = req_readline(fd, caLine, 1024); d110 3 a112 2 caLine[n] = '\0'; /* fprintf(stderr, "child: [%03d] recv: <%s>\n", fd, caLine); */ a114 3 /* simulate a little bit more of processing */ /* pth_usleep(10000); */ d132 18 d154 1 a154 1 pth_attr_t attr; d159 2 d217 2 a218 1 if ((req_socket[req_num] = pth_accept(s, NULL, NULL)) == -1) { d226 3 a228 1 fprintf(stderr, "parent: connection accepted [%03d]\n", req_socket[req_num]); @ 1.2 log @*** empty log message *** @ text @d17 1 a17 1 pth_sleep(pth_time(10,0)); d51 3 d70 1 a70 1 /* pth_sleep(pth_time(0, 10000)); */ d129 3 @ 1.1 log @Initial revision @ text @d63 1 a63 1 // fprintf(stderr, "child: [%03d] recv: <%s>\n", fd, caLine); d67 1 a67 1 // pth_sleep(pth_time(0, 10000)); @ 1.1.1.1 log @Import of PTH into CVS @ text @@