diff --git a/test-server/test-server.c b/test-server/test-server.c index c7861cf5..857cae2d 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -33,50 +33,12 @@ static int close_testing; #ifdef EXTERNAL_POLL #define LWS_NO_FORK -#ifndef MAX_CLIENTS -#define MAX_POLL_ELEMENTS 100 -#else -#define MAX_POLL_ELEMENTS (MAX_CLIENTS) -#endif -struct poll_hash_map { - int fd; - int index; -}; - -#define POLL_HASH_BITS 8 - -#define POLL_HASH_BUCKETS (1 << POLL_HASH_BITS) -#define POLL_ENTRIES_PER_BUCKET (MAX_POLL_ELEMENTS / (1 << (POLL_HASH_BITS - 2))) -#define POLL_HASH(num) (num & (POLL_HASH_BUCKETS - 1)) +#define MAX_POLL_ELEMENTS 32000 struct pollfd pollfds[MAX_POLL_ELEMENTS]; -struct poll_hash_map pollfd_maps[POLL_HASH_BUCKETS][POLL_ENTRIES_PER_BUCKET]; -int pollfd_count[POLL_HASH_BUCKETS]; -int count_pollfds = 0; - -static int find_poll_map_index(int hash, int fd) -{ - int n; - - for (n = 0; n < pollfd_count[hash]; n++) - if (pollfd_maps[hash][n].fd == fd) - return n; - - return -1; -} - -static int find_pollfd_index(int fd) -{ - int n; - int hash = POLL_HASH(fd); - - n = find_poll_map_index(hash, fd); - if (n < 0) - return n; - - return pollfd_maps[hash][n].index; -} +int fd_lookup[MAX_POLL_ELEMENTS]; +int count_pollfds; #endif /* EXTERNAL_POLL */ @@ -126,11 +88,6 @@ static const struct serveable whitelist[] = { { "/test.html", "text/html" }, }; -/* some versions of gcc see a false positive here, workaround */ -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - /* this protocol server (always the first one) just knows how to do HTTP */ static int callback_http(struct libwebsocket_context *context, @@ -143,8 +100,7 @@ static int callback_http(struct libwebsocket_context *context, char buf[256]; int n; #ifdef EXTERNAL_POLL - int m, m1; - int hash, hash1; + int m; int fd = (int)(long)user; #endif @@ -199,95 +155,36 @@ static int callback_http(struct libwebsocket_context *context, */ case LWS_CALLBACK_ADD_POLL_FD: - if (count_pollfds == MAX_POLL_ELEMENTS) { + + if (count_pollfds >= MAX_POLL_ELEMENTS) { fprintf(stderr, "LWS_CALLBACK_ADD_POLL_FD: too many sockets to track\n"); return 1; } - hash = POLL_HASH(fd); - if (pollfd_count[hash] == POLL_ENTRIES_PER_BUCKET) { - fprintf(stderr, "LWS_CALLBACK_ADD_POLL_FD: hash table overflow\n"); - return 1; - } -// fprintf(stderr, "Adding fd %d at pollfd_maps[%d][%d], pollfds[%d]\n", fd, hash, pollfd_count[hash], count_pollfds); - - pollfd_maps[hash][pollfd_count[hash]].fd = fd; - pollfd_maps[hash][pollfd_count[hash]++].index = count_pollfds; - - pollfds[count_pollfds].fd = (int)(long)user; - pollfds[count_pollfds].events = (int)len; + fd_lookup[fd] = count_pollfds; + pollfds[count_pollfds].fd = fd; + pollfds[count_pollfds].events = (int)(long)len; pollfds[count_pollfds++].revents = 0; break; case LWS_CALLBACK_DEL_POLL_FD: - hash = POLL_HASH(fd); - n = find_poll_map_index(hash, fd); - if (n < 0) { - fprintf(stderr, "unable to find fd %d in poll_maps\n", fd); - return 1; - } - m = pollfd_maps[hash][n].index; - - assert(pollfds[m].fd == fd); - assert(count_pollfds); - assert(pollfd_count[hash]); - -// fprintf(stderr, "Removing fd %d at pollfd_maps[%d][%d], pollfds[%d]\n", fd, hash, n, m); - - /* - * swap the end guy into our vacant slot... - * works ok if n is the end guy - */ - - count_pollfds--; - if (count_pollfds) { - - /* end guy... */ - hash1 = POLL_HASH(pollfds[count_pollfds].fd); - m1 = find_poll_map_index(hash1, pollfds[count_pollfds].fd); - /* your index has changed... */ - pollfd_maps[hash1][m1].index = m; - - pollfds[m] = pollfds[count_pollfds]; - pollfds[count_pollfds].fd = -1; - } - - /* - * similar trick with hashtable - * old end guy goes into vacant slot in hash table - */ - - pollfd_count[hash]--; - if (pollfd_count[hash]) { - pollfd_maps[hash][n].index = pollfd_maps[hash][pollfd_count[hash]].index; - pollfd_maps[hash][n].fd = pollfd_maps[hash][pollfd_count[hash]].fd; - } - + if (!--count_pollfds) + break; + m = fd_lookup[fd]; + /* have the last guy take up the vacant slot */ + pollfds[m] = pollfds[count_pollfds]; + fd_lookup[pollfds[count_pollfds].fd] = m; break; case LWS_CALLBACK_SET_MODE_POLL_FD: - n = find_pollfd_index(fd); - if (n < 0) { - fprintf(stderr, "unable to find fd %d\n", fd); - return 1; - } - if(pollfds[n].fd != fd) { - fprintf(stderr, "Setting fd %d, found at pollfd_index %d, actually fd %d\n", fd, n, pollfds[n].fd); - assert(0); - } - pollfds[n].events |= (int)(long)len; + pollfds[fd_lookup[fd]].events |= (int)(long)len; break; case LWS_CALLBACK_CLEAR_MODE_POLL_FD: - n = find_pollfd_index(fd); - if (n < 0) { - fprintf(stderr, "unable to find fd %d\n", fd); - return 1; - } - assert(pollfds[n].fd == fd); - pollfds[n].events &= ~(int)(long)len; + pollfds[fd_lookup[fd]].events &= ~(int)(long)len; break; #endif + default: break; } @@ -295,10 +192,6 @@ static int callback_http(struct libwebsocket_context *context, return 0; } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - /* * this is just an example of parsing handshake headers, you don't need this * in your code unless you will filter allowing connections by the header