gdb: fix regression in gdb_port command
[fw/openocd] / src / server / server.c
index 7416784c768b18bc1adec1cb3263b72600c0a702..f762704dd3412f6c6761aeca0c14518311093626 100644 (file)
 #endif
 
 #include "server.h"
-#include "target.h"
+#include <target/target.h>
+#include "openocd.h"
+#include "tcl_server.h"
+#include "telnet_server.h"
 
 #include <signal.h>
 
@@ -285,16 +288,14 @@ int remove_services(void)
        return ERROR_OK;
 }
 
-extern void openocd_sleep_prelude(void);
-extern void openocd_sleep_postlude(void);
-
 int server_loop(struct command_context *command_context)
 {
        struct service *service;
 
+       bool poll = true;
+
        /* used in select() */
        fd_set read_fds;
-       struct timeval tv;
        int fd_max;
 
        /* used in accept() */
@@ -305,13 +306,9 @@ int server_loop(struct command_context *command_context)
                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;
-
        while (!shutdown_openocd)
        {
-               /* monitor sockets for acitvity */
+               /* monitor sockets for activity */
                fd_max = 0;
                FD_ZERO(&read_fds);
 
@@ -351,12 +348,24 @@ int server_loop(struct command_context *command_context)
 #endif
 #endif
 
-               openocd_sleep_prelude();
-               kept_alive();
-
-               /* Only while we're sleeping we'll let others run */
-               retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
-               openocd_sleep_postlude();
+               struct timeval tv;
+               tv.tv_sec = 0;
+               if (poll)
+               {
+                       /* we're just polling this iteration, this is faster on embedded
+                        * hosts */
+                       tv.tv_usec = 0;
+                       retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
+               } else
+               {
+                       /* Every 100ms */
+                       tv.tv_usec = 100000;
+                       /* Only while we're sleeping we'll let others run */
+                       openocd_sleep_prelude();
+                       kept_alive();
+                       retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
+                       openocd_sleep_postlude();
+               }
 
                if (retval == -1)
                {
@@ -385,15 +394,20 @@ int server_loop(struct command_context *command_context)
 #endif
                }
 
-               target_call_timer_callbacks();
-               process_jim_events ();
-
                if (retval == 0)
                {
-                       /* do regular tasks after at most 100ms */
-                       tv.tv_sec = 0;
-                       tv.tv_usec = 10000;
+                       /* We only execute these callbacks when there was nothing to do or we timed out */
+                       target_call_timer_callbacks();
+                       process_jim_events(command_context);
+
                        FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case!  */
+
+                       /* We timed out/there was nothing to do, timeout rather than poll next time */
+                       poll = false;
+               } else
+               {
+                       /* There was something to do, next time we'll just poll */
+                       poll = true;
                }
 
                for (service = services; service; service = service->next)
@@ -487,8 +501,12 @@ void sig_handler(int sig) {
 }
 #endif
 
-int server_init(void)
+int server_preinit(void)
 {
+       /* this currently only calls WSAStartup on native win32 systems
+        * before any socket operations are performed.
+        * This is an issue if you call init in your config script */
+
 #ifdef _WIN32
        WORD wVersionRequested;
        WSADATA wsaData;
@@ -521,6 +539,15 @@ int server_init(void)
        return ERROR_OK;
 }
 
+int server_init(struct command_context *cmd_ctx)
+{
+       int ret = tcl_init(cmd_ctx);
+       if (ERROR_OK != ret)
+               return ret;
+
+       return telnet_init("Open On-Chip Debugger");
+}
+
 int server_quit(void)
 {
        remove_services();
@@ -541,26 +568,39 @@ COMMAND_HANDLER(handle_shutdown_command)
        return ERROR_COMMAND_CLOSE_CONNECTION;
 }
 
-int server_register_commands(struct command_context *context)
+static const struct command_registration server_command_handlers[] = {
+       {
+               .name = "shutdown",
+               .handler = &handle_shutdown_command,
+               .mode = COMMAND_ANY,
+               .help = "shut the server down",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+int server_register_commands(struct command_context *cmd_ctx)
 {
-       register_command(context, NULL, "shutdown",
-                       handle_shutdown_command, COMMAND_ANY,
-                       "shut the server down");
+       int retval = telnet_register_commands(cmd_ctx);
+       if (ERROR_OK != retval)
+               return retval;
 
-       return ERROR_OK;
-}
+       retval = tcl_register_commands(cmd_ctx);
+       if (ERROR_OK != retval)
+               return retval;
 
+       return register_commands(cmd_ctx, NULL, server_command_handlers);
+}
 
 SERVER_PORT_COMMAND()
 {
-       switch (argc) {
+       switch (CMD_ARGC) {
        case 0:
-               command_print(cmd_ctx, "%d", *out);
+               command_print(CMD_CTX, "%d", *out);
                break;
        case 1:
        {
                uint16_t port;
-               COMMAND_PARSE_NUMBER(u16, args[0], port);
+               COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
                *out = port;
                break;
        }