optimize extpoll fd delete
[profile/ivi/libwebsockets.git] / test-server / test-server-extpoll.c
index 29595a1..5025f4d 100644 (file)
 #include <getopt.h>
 #include <string.h>
 #include <sys/time.h>
+#ifdef __MINGW32__
+#include "../win32port/win32helpers/websock-w32.h"
+#else
+#ifdef __MINGW64__
+#include "../win32port/win32helpers/websock-w32.h"
+#else
 #include <poll.h>
+#endif
+#endif
 
 #include "../lib/libwebsockets.h"
 
@@ -68,7 +76,7 @@ enum demo_protocols {
 };
 
 
-#define LOCAL_RESOURCE_PATH DATADIR"/libwebsockets-test-server"
+#define LOCAL_RESOURCE_PATH INSTALL_DATADIR"/libwebsockets-test-server"
 
 /* this protocol server (always the first one) just knows how to do HTTP */
 
@@ -97,7 +105,8 @@ static int callback_http(struct libwebsocket_context * this,
                if (libwebsockets_serve_http_file(wsi,
                                  LOCAL_RESOURCE_PATH"/test.html", "text/html"))
                        fprintf(stderr, "Failed to send HTTP file\n");
-               break;
+               /* we are done with this connnection */
+               return 1;
 
        /*
         * callback for confirming to continue with client IP appear in
@@ -130,13 +139,18 @@ static int callback_http(struct libwebsocket_context * this,
                break;
 
        case LWS_CALLBACK_DEL_POLL_FD:
-               for (n = 0; n < count_pollfds; n++)
-                       if (pollfds[n].fd == (int)(long)user)
-                               while (n < count_pollfds) {
-                                       pollfds[n] = pollfds[n + 1];
-                                       n++;
-                               }
-               count_pollfds--;
+               for (n = 0; n < count_pollfds; n++) {
+                       if (pollfds[n].fd != (int)(long)user)
+                               continue;
+                       /*
+                        * swap the end guy into our vacant slot...
+                        * works ok if n is the end guy
+                        */
+                       pollfds[n] = pollfds[count_pollfds - 1];
+                       pollfds[count_pollfds - 1].fd = -1;
+                       count_pollfds--;
+                       break;
+               }
                break;
 
        case LWS_CALLBACK_SET_MODE_POLL_FD:
@@ -192,6 +206,7 @@ dump_handshake_info(struct lws_tokens *lwst)
                [WSI_TOKEN_ACCEPT] = "Accept",
                [WSI_TOKEN_NONCE] = "Nonce",
                [WSI_TOKEN_HTTP] = "Http",
+               [WSI_TOKEN_MUXURL]      = "MuxURL",
        };
        
        for (n = 0; n < WSI_TOKEN_COUNT; n++) {
@@ -244,7 +259,7 @@ callback_dumb_increment(struct libwebsocket_context * this,
                n = sprintf((char *)p, "%d", pss->number++);
                n = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT);
                if (n < 0) {
-                       fprintf(stderr, "ERROR writing to socket");
+                       fprintf(stderr, "ERROR %d writing to socket\n", n);
                        return 1;
                }
                break;
@@ -311,7 +326,7 @@ callback_lws_mirror(struct libwebsocket_context * this,
                libwebsocket_callback_on_writable(this, wsi);
                break;
 
-       case LWS_CALLBACK_CLIENT_WRITEABLE:
+       case LWS_CALLBACK_SERVER_WRITEABLE:
 
                if (pss->ringbuffer_tail != ringbuffer_head) {
 
@@ -322,7 +337,7 @@ callback_lws_mirror(struct libwebsocket_context * this,
                                                                LWS_WRITE_TEXT);
 
                        if (n < 0) {
-                               fprintf(stderr, "ERROR writing to socket");
+                               fprintf(stderr, "ERROR %d writing to socket\n", n);
                                exit(1);
                        }
 
@@ -393,29 +408,30 @@ callback_lws_mirror(struct libwebsocket_context * this,
 
 static struct libwebsocket_protocols protocols[] = {
        /* first protocol must always be HTTP handler */
-       [PROTOCOL_HTTP] = {
-               .name = "http-only",
-               .callback = callback_http,
+
+       {
+               "http-only",            /* name */
+               callback_http,          /* callback */
+               0                       /* per_session_data_size */
        },
-       [PROTOCOL_DUMB_INCREMENT] = {
-               .name = "dumb-increment-protocol",
-               .callback = callback_dumb_increment,
-               .per_session_data_size =
-                               sizeof(struct per_session_data__dumb_increment),
+       {
+               "dumb-increment-protocol",
+               callback_dumb_increment,
+               sizeof(struct per_session_data__dumb_increment),
        },
-       [PROTOCOL_LWS_MIRROR] = {
-               .name = "lws-mirror-protocol",
-               .callback = callback_lws_mirror,
-               .per_session_data_size =
-                               sizeof(struct per_session_data__lws_mirror),
+       {
+               "lws-mirror-protocol",
+               callback_lws_mirror,
+               sizeof(struct per_session_data__lws_mirror)
        },
-       [DEMO_PROTOCOL_COUNT] = {  /* end of list */
-               .callback = NULL
+       {
+               NULL, NULL, 0           /* End of list */
        }
 };
 
 static struct option options[] = {
        { "help",       no_argument,            NULL, 'h' },
+       { "debug",      required_argument,      NULL, 'd' },
        { "port",       required_argument,      NULL, 'p' },
        { "ssl",        no_argument,            NULL, 's' },
        { "killmask",   no_argument,            NULL, 'k' },
@@ -427,9 +443,9 @@ int main(int argc, char **argv)
 {
        int n = 0;
        const char *cert_path =
-                           LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
+                          LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
        const char *key_path =
-                       LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
+                      LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
        unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 1024 +
                                                  LWS_SEND_BUFFER_POST_PADDING];
        int port = 7681;
@@ -438,17 +454,20 @@ int main(int argc, char **argv)
        int opts = 0;
        unsigned int oldus = 0;
        char interface_name[128] = "";
-       const char * interface = NULL;
+       const char *interface_ptr = NULL;
 
        fprintf(stderr, "libwebsockets test server with external poll()\n"
                        "(C) Copyright 2010-2011 Andy Green <andy@warmcat.com> "
                                                    "licensed under LGPL2.1\n");
 
        while (n >= 0) {
-               n = getopt_long(argc, argv, "i:khsp:", options, NULL);
+               n = getopt_long(argc, argv, "i:khsp:d:", options, NULL);
                if (n < 0)
                        continue;
                switch (n) {
+               case 'd':
+                       lws_set_log_level(atoi(optarg), NULL);
+                       break;
                case 's':
                        use_ssl = 1;
                        break;
@@ -461,11 +480,12 @@ int main(int argc, char **argv)
                case 'i':
                        strncpy(interface_name, optarg, sizeof interface_name);
                        interface_name[(sizeof interface_name) - 1] = '\0';
-                       interface = interface_name;
+                       interface_ptr = interface_name;
                        break;
                case 'h':
                        fprintf(stderr, "Usage: test-server "
-                                            "[--port=<p>] [--ssl]\n");
+                                       "[--port=<p>] [--ssl] "
+                                       "[-d <log bitfield>]\n");
                        exit(1);
                }
        }
@@ -473,8 +493,10 @@ int main(int argc, char **argv)
        if (!use_ssl)
                cert_path = key_path = NULL;
 
-       context = libwebsocket_create_context(port, interface, protocols,
-                                       cert_path, key_path, -1, -1, opts);
+       context = libwebsocket_create_context(port, interface_ptr, protocols,
+                                       libwebsocket_internal_extensions,
+                                       cert_path, key_path, NULL, -1, -1,
+                                       opts, NULL);
        if (context == NULL) {
                fprintf(stderr, "libwebsocket init failed\n");
                return -1;
@@ -507,8 +529,9 @@ int main(int argc, char **argv)
                                        * match anything under libwebsockets
                                        * control
                                        */
-                                       libwebsocket_service_fd(context,
-                                                                  &pollfds[n]);
+                                       if (libwebsocket_service_fd(context,
+                                                                 &pollfds[n]))
+                                               goto done;
 
                /* do our broadcast periodically */