Windows: Add priority support when a child process is created
authorcaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 20 Feb 2010 09:20:04 +0000 (09:20 +0000)
committercaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 20 Feb 2010 09:20:04 +0000 (09:20 +0000)
and add documentation for that.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@46330 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore/Ecore.h
src/lib/ecore/ecore_exe.c
src/lib/ecore/ecore_exe_win32.c

index 96bf60f..41ed0d3 100644 (file)
@@ -107,6 +107,17 @@ extern "C" {
      };
    typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags;
 
+   enum _Ecore_Exe_Win32_Priority
+     {
+       ECORE_EXE_WIN32_PRIORITY_IDLE, /**< Idle priority, for monitoring the system */
+       ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL, /**< Below default priority */
+       ECORE_EXE_WIN32_PRIORITY_NORMAL, /**< Default priority */
+       ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL, /**< Above default priority */
+       ECORE_EXE_WIN32_PRIORITY_HIGH, /**< High priority, use with care as other threads in the system will not get processor time */
+       ECORE_EXE_WIN32_PRIORITY_REALTIME /**< Realtime priority, should be almost never used as it can interrupt system threads that manage mouse input, keyboard input, and background disk flushing */
+     };
+   typedef enum _Ecore_Exe_Win32_Priority Ecore_Exe_Win32_Priority;
+
    enum _Ecore_Poller_Type /* Poller types */
      {
        ECORE_POLLER_CORE = 0 /**< The core poller interval */
index 2af62ce..556e031 100644 (file)
@@ -315,10 +315,17 @@ static int run_pri = ECORE_EXE_PRIORITY_INHERIT;
  * Sets the priority at which to launch processes
  *
  * This sets the priority of processes run by ecore_exe_run() and
- * ecore_exe_pipe_run(). If set to ECORE_EXE_PRIORITY_INHERIT child processes
- * inherit the priority of their parent. This is the default.
+ * ecore_exe_pipe_run().
+ * @li On Windows, the child process is created by default with the
+ * #ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling
+ * process is in #ECORE_EXE_WIN32_PRIORITY_IDLE or
+ * #ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the
+ * child process inherits this priority.
+ * @li On other platforms, if set to #ECORE_EXE_PRIORITY_INHERIT child
+ * processes inherits the priority of their parent. This is the default.
  *
- * @param   pri value -20 to 19 or ECORE_EXE_PRIORITY_INHERIT
+ * @param   pri value a Ecore_Exe_Win32_Priority value on Windows, -20
+ * to 19 or ECORE_EXE_PRIORITY_INHERIT on other OS.
  * @ingroup Ecore_Exe_Basic_Group
  */
 EAPI void
index ed8cf8e..0b195f7 100644 (file)
@@ -4,9 +4,7 @@
 
 /*
  * TODO:
- * - manage priority
- * - manage I/O pipes
- * - add events for data and error
+ * - manage I/O pipes (several ones, and stdin)
  * - manage SetConsoleCtrlHandler ?
  */
 
@@ -121,14 +119,57 @@ _ecore_exe_shutdown(void)
       ecore_exe_free(exes);
 }
 
+static int run_pri = NORMAL_PRIORITY_CLASS;
+
 EAPI void
 ecore_exe_run_priority_set(int pri)
 {
+   switch (pri)
+     {
+     case ECORE_EXE_WIN32_PRIORITY_IDLE:
+       run_pri = IDLE_PRIORITY_CLASS;
+       break;
+     case ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL:
+       run_pri = BELOW_NORMAL_PRIORITY_CLASS;
+       break;
+     case ECORE_EXE_WIN32_PRIORITY_NORMAL:
+       run_pri = NORMAL_PRIORITY_CLASS;
+       break;
+     case ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL:
+       run_pri = ABOVE_NORMAL_PRIORITY_CLASS;
+       break;
+     case ECORE_EXE_WIN32_PRIORITY_HIGH:
+       run_pri = HIGH_PRIORITY_CLASS;
+       break;
+     case ECORE_EXE_WIN32_PRIORITY_REALTIME:
+       run_pri = REALTIME_PRIORITY_CLASS;
+       break;
+     default:
+       break;
+     }
 }
 
 EAPI int
 ecore_exe_run_priority_get(void)
 {
+   switch (run_pri)
+     {
+     case IDLE_PRIORITY_CLASS:
+       return ECORE_EXE_WIN32_PRIORITY_IDLE;
+     case BELOW_NORMAL_PRIORITY_CLASS:
+       return ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL;
+     case NORMAL_PRIORITY_CLASS:
+       return ECORE_EXE_WIN32_PRIORITY_NORMAL;
+     case ABOVE_NORMAL_PRIORITY_CLASS:
+       return ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL;
+     case HIGH_PRIORITY_CLASS:
+       return ECORE_EXE_WIN32_PRIORITY_HIGH;
+     case REALTIME_PRIORITY_CLASS:
+       return ECORE_EXE_WIN32_PRIORITY_REALTIME;
+       /* default should not be reached */
+     default:
+       return ECORE_EXE_WIN32_PRIORITY_NORMAL;
+     }
 }
 
 EAPI Ecore_Exe *
@@ -155,7 +196,6 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
      /* We need something to auto pipe. */
      flags |= ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR;
 
-   printf ("create pipes...\n");
    exe->flags = flags;
    if (exe->flags & ECORE_EXE_PIPE_READ)
      if (!_ecore_exe_win32_pipes_set(exe))
@@ -168,7 +208,6 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
    if (exe->flags & ECORE_EXE_PIPE_ERROR)
      if (!_ecore_exe_win32_pipes_set(exe))
        goto close_pipes;
-   printf ("create pipes finished\n");
 
    if ((exe->flags & ECORE_EXE_USE_SH) ||
        ((ret = strrstr(exe_cmd, ".bat")) && (ret[4] == '\0')))
@@ -195,7 +234,7 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
    /* FIXME: gerer la priorite */
 
    if (!CreateProcess(NULL, exe->cmd, NULL, NULL, TRUE,
-                      0, NULL, NULL, &si, &pi))
+                      run_pri | CREATE_SUSPENDED, NULL, NULL, &si, &pi))
      goto free_exe_cmd;
 
    /* be sure that the child process is running */
@@ -214,6 +253,9 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
                                      FALSE, pi.dwProcessId)))
      goto close_thread;
 
+   if (ResumeThread(exe->thread) == ((DWORD)-1))
+     goto close_process2;
+
    printf (" * 10\n");
    exe->h_close = ecore_main_win32_handler_add(exe->process2, _ecore_exe_close_cb, exe);
    if (!exe->h_close) goto close_process2;