]> git.sur5r.net Git - openocd/blobdiff - src/server/server.c
doc: not all debug adapters are "dongles"
[openocd] / src / server / server.c
index b28aa500252bdea32fe7ca29fb8a0caec35330be..173beb8656f08ffb4b4d0c37ea5ddbaa03fbd8b6 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>
 
@@ -290,9 +292,10 @@ 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() */
@@ -303,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);
 
@@ -349,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)
                {
@@ -383,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)
@@ -485,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;
@@ -519,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();
@@ -534,20 +563,35 @@ int server_quit(void)
 /* tell the server we want to shut down */
 COMMAND_HANDLER(handle_shutdown_command)
 {
+       LOG_USER("shutdown command invoked");
+
        shutdown_openocd = 1;
 
-       return ERROR_COMMAND_CLOSE_CONNECTION;
+       return ERROR_OK;
 }
 
-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()
 {