X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fserver%2Fserver.c;h=aad98747445bdeb68c42d6c84c88655cf54087bc;hb=f370d70670bd5e30befe6fbfbc8d472e760f032b;hp=6e43cf7cf27f269dbf67af9654ed9f2428a155a3;hpb=e482118106c63edd3c9f6647e4232e90b4c16066;p=fw%2Fopenocd diff --git a/src/server/server.c b/src/server/server.c index 6e43cf7cf..aad987474 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -2,6 +2,9 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -37,6 +40,9 @@ #include #include #include +#ifndef _WIN32 +#include +#endif service_t *services = NULL; @@ -49,6 +55,7 @@ int add_connection(service_t *service, command_context_t *cmd_ctx) unsigned int address_size; connection_t *c, **p; int retval; + int flag=1; c = malloc(sizeof(connection_t)); c->fd = -1; @@ -60,17 +67,27 @@ int add_connection(service_t *service, command_context_t *cmd_ctx) c->next = NULL; address_size = sizeof(c->sin); + c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); - + + /* This increases performance dramatically for e.g. GDB load which + * does not have a sliding window protocol. */ + retval=setsockopt(c->fd, /* socket affected */ + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (char *)&flag, /* the cast is historical cruft */ + sizeof(int)); /* length of option value */ + + LOG_INFO("accepting '%s' connection from %i", service->name, c->sin.sin_port); if ((retval = service->new_connection(c)) == ERROR_OK) { - INFO("accepted '%s' connection from %i", service->name, c->sin.sin_port); } else { close_socket(c->fd); - INFO("attempted '%s' connection rejected", service->name); + LOG_ERROR("attempted '%s' connection rejected", service->name); free(c); + return retval; } /* add to the end of linked list */ @@ -88,7 +105,7 @@ int remove_connection(service_t *service, connection_t *connection) connection_t *c; /* find connection */ - while(c = *p) + while((c = *p)) { if (c->fd == connection->fd) { @@ -132,7 +149,7 @@ int add_service(char *name, enum connection_type type, unsigned short port, int if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ERROR("error creating socket: %s", strerror(errno)); + LOG_ERROR("error creating socket: %s", strerror(errno)); exit(-1); } @@ -147,13 +164,26 @@ int add_service(char *name, enum connection_type type, unsigned short port, int if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) { - ERROR("couldn't bind to socket: %s", strerror(errno)); + LOG_ERROR("couldn't bind to socket: %s", strerror(errno)); exit(-1); } +#ifndef _WIN32 + int segsize=65536; + setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG, &segsize, sizeof(int)); +#endif + int window_size = 128 * 1024; + + /* These setsockopt()s must happen before the listen() */ + + setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF, + (char *)&window_size, sizeof(window_size)); + setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF, + (char *)&window_size, sizeof(window_size)); + if (listen(c->fd, 1) == -1) { - ERROR("couldn't listen on socket: %s", strerror(errno)); + LOG_ERROR("couldn't listen on socket: %s", strerror(errno)); exit(-1); } @@ -166,11 +196,11 @@ int add_service(char *name, enum connection_type type, unsigned short port, int int remove_service(unsigned short port) { - service_t **p = services; + service_t **p = &services; service_t *c; /* find service */ - while(c = *p) + while((c = *p)) { if (c->port == port) { @@ -192,7 +222,7 @@ int remove_service(unsigned short port) return ERROR_OK; } -int remove_services() +int remove_services(void) { service_t *c = services; @@ -219,6 +249,9 @@ int remove_services() return ERROR_OK; } +extern void openocd_sleep_prelude(void); +extern void openocd_sleep_postlude(void); + int server_loop(command_context_t *command_context) { service_t *service; @@ -233,9 +266,9 @@ int server_loop(command_context_t *command_context) #ifndef _WIN32 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - ERROR("couldn't set SIGPIPE to SIG_IGN"); + LOG_ERROR("couldn't set SIGPIPE to SIG_IGN"); #endif - + /* do regular tasks after at most 10ms */ tv.tv_sec = 0; tv.tv_usec = 10000; @@ -273,12 +306,18 @@ int server_loop(command_context_t *command_context) } #ifndef _WIN32 +#ifndef BUILD_ECOSBOARD /* add STDIN to read_fds */ FD_SET(fileno(stdin), &read_fds); +#endif #endif + openocd_sleep_prelude(); + kept_alive(); + // Only while we're sleeping we'll let others run retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv); - + openocd_sleep_postlude(); + if (retval == -1) { #ifdef _WIN32 @@ -289,18 +328,18 @@ int server_loop(command_context_t *command_context) FD_ZERO(&read_fds); else { - ERROR("error during select: %s", strerror(errno)); + LOG_ERROR("error during select: %s", strerror(errno)); exit(-1); } #else if (errno == EINTR) - { + { FD_ZERO(&read_fds); - } + } else { - ERROR("error during select: %s", strerror(errno)); + LOG_ERROR("error during select: %s", strerror(errno)); exit(-1); } #endif @@ -313,7 +352,7 @@ int server_loop(command_context_t *command_context) /* do regular tasks after at most 100ms */ tv.tv_sec = 0; tv.tv_usec = 10000; - FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */ + FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */ } for (service = services; service; service = service->next) @@ -323,7 +362,7 @@ int server_loop(command_context_t *command_context) && (FD_ISSET(service->fd, &read_fds))) { if (service->max_connections > 0) - { + { add_connection(service, command_context); } else @@ -333,7 +372,7 @@ int server_loop(command_context_t *command_context) int tmp_fd; tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); close_socket(tmp_fd); - INFO("rejected '%s' connection, no more connections allowed", service->name); + LOG_INFO("rejected '%s' connection, no more connections allowed", service->name); } } @@ -350,7 +389,7 @@ int server_loop(command_context_t *command_context) { connection_t *next = c->next; remove_connection(service, c); - INFO("dropped '%s' connection", service->name); + LOG_INFO("dropped '%s' connection", service->name); c = next; continue; } @@ -361,6 +400,7 @@ int server_loop(command_context_t *command_context) } #ifndef _WIN32 +#ifndef BUILD_ECOSBOARD if (FD_ISSET(fileno(stdin), &read_fds)) { if (getc(stdin) == 'x') @@ -368,6 +408,7 @@ int server_loop(command_context_t *command_context) shutdown_openocd = 1; } } +#endif #else MSG msg; while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) @@ -393,7 +434,7 @@ void sig_handler(int sig) { } #endif -int server_init() +int server_init(void) { #ifdef _WIN32 WORD wVersionRequested; @@ -403,7 +444,7 @@ int server_init() if (WSAStartup(wVersionRequested, &wsaData) != 0) { - ERROR("Failed to Open Winsock"); + LOG_ERROR("Failed to Open Winsock"); exit(-1); } @@ -419,7 +460,7 @@ int server_init() return ERROR_OK; } -int server_quit() +int server_quit(void) { remove_services();