Merge pull request #2721 from ludovic-henry/fix-mono_ms_ticks
[mono.git] / mono / utils / mono-proclib.c
index 9b8585a392afdda7bca558220f32fb24d81dbcf5..efd732d6d56b7592b9de709a4d34c352e42baf8f 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright 2008-2011 Novell Inc
  * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include "config.h"
@@ -26,6 +27,7 @@
 #if defined(_POSIX_VERSION)
 #include <sys/errno.h>
 #include <sys/param.h>
+#include <errno.h>
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -354,22 +356,35 @@ get_process_stat_item (int pid, int pos, int sum, MonoProcessError *error)
        mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT, th_count;
        thread_array_t th_array;
        size_t i;
+       kern_return_t ret;
 
        if (pid == getpid ()) {
                /* task_for_pid () doesn't work on ios, even for the current process */
                task = mach_task_self ();
        } else {
-               if (task_for_pid (mach_task_self (), pid, &task) != KERN_SUCCESS)
+               do {
+                       ret = task_for_pid (mach_task_self (), pid, &task);
+               } while (ret == KERN_ABORTED);
+
+               if (ret != KERN_SUCCESS)
                        RET_ERROR (MONO_PROCESS_ERROR_NOT_FOUND);
        }
 
-       if (task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count) != KERN_SUCCESS) {
+       do {
+               ret = task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
+       } while (ret == KERN_ABORTED);
+
+       if (ret != KERN_SUCCESS) {
                if (pid != getpid ())
                        mach_port_deallocate (mach_task_self (), task);
                RET_ERROR (MONO_PROCESS_ERROR_OTHER);
        }
+
+       do {
+               ret = task_threads (task, &th_array, &th_count);
+       } while (ret == KERN_ABORTED);
        
-       if (task_threads(task, &th_array, &th_count) != KERN_SUCCESS) {
+       if (ret  != KERN_SUCCESS) {
                if (pid != getpid ())
                        mach_port_deallocate (mach_task_self (), task);
                RET_ERROR (MONO_PROCESS_ERROR_OTHER);
@@ -380,7 +395,11 @@ get_process_stat_item (int pid, int pos, int sum, MonoProcessError *error)
                
                struct thread_basic_info th_info;
                mach_msg_type_number_t th_info_count = THREAD_BASIC_INFO_COUNT;
-               if (thread_info(th_array[i], THREAD_BASIC_INFO, (thread_info_t)&th_info, &th_info_count) == KERN_SUCCESS) {
+               do {
+                       ret = thread_info(th_array[i], THREAD_BASIC_INFO, (thread_info_t)&th_info, &th_info_count);
+               } while (ret == KERN_ABORTED);
+
+               if (ret == KERN_SUCCESS) {
                        thread_user_time = th_info.user_time.seconds + th_info.user_time.microseconds / 1e6;
                        thread_system_time = th_info.system_time.seconds + th_info.system_time.microseconds / 1e6;
                        //thread_percent = (double)th_info.cpu_usage / TH_USAGE_SCALE;
@@ -493,16 +512,25 @@ get_pid_status_item (int pid, const char *item, MonoProcessError *error, int mul
        task_t task;
        struct task_basic_info t_info;
        mach_msg_type_number_t th_count = TASK_BASIC_INFO_COUNT;
+       kern_return_t mach_ret;
 
        if (pid == getpid ()) {
                /* task_for_pid () doesn't work on ios, even for the current process */
                task = mach_task_self ();
        } else {
-               if (task_for_pid (mach_task_self (), pid, &task) != KERN_SUCCESS)
+               do {
+                       mach_ret = task_for_pid (mach_task_self (), pid, &task);
+               } while (mach_ret == KERN_ABORTED);
+
+               if (mach_ret != KERN_SUCCESS)
                        RET_ERROR (MONO_PROCESS_ERROR_NOT_FOUND);
        }
-       
-       if (task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &th_count) != KERN_SUCCESS) {
+
+       do {
+               mach_ret = task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &th_count);
+       } while (mach_ret == KERN_ABORTED);
+
+       if (mach_ret != KERN_SUCCESS) {
                if (pid != getpid ())
                        mach_port_deallocate (mach_task_self (), task);
                RET_ERROR (MONO_PROCESS_ERROR_OTHER);