Make objects enumerable by type. Fix another thread initialization problem.
authorcoderain <coderain@sdf.org>
Wed, 15 Feb 2017 23:59:09 +0000 (00:59 +0100)
committercoderain <coderain@sdf.org>
Wed, 15 Feb 2017 23:59:09 +0000 (00:59 +0100)
kernel/include/object.h
kernel/include/process.h
kernel/src/object.c
kernel/src/process.c
kernel/src/thread.c
kernel/src/user.c

index dcd3cc9e3b9a1ad59a799f972fdaf9d9152a6eb4..da4856d3b205f3939296b67a5fd1b82de1834293 100644 (file)
@@ -36,6 +36,7 @@ typedef enum
     OBJECT_THREAD,
     OBJECT_MEMORY,
     OBJECT_SEMAPHORE,
+
     OBJECT_TYPE_MAX
 } object_type_t;
 
@@ -47,7 +48,8 @@ typedef enum
 
 typedef struct
 {
-    list_entry_t list;
+    list_entry_t by_name_list;
+    list_entry_t by_type_list;
     char *name;
     qword_t ref_count, open_count;
     object_type_t type;
@@ -66,5 +68,6 @@ void close_object_internal(object_t *obj);
 dword_t close_object(handle_t handle);
 dword_t query_handle(handle_t handle, handle_info_type_t type, void *buffer, size_t size);
 dword_t duplicate_handle(handle_t source_process, handle_t handle, handle_t dest_process, handle_t *duplicate);
+dword_t enum_objects_by_type(object_type_t type, object_t **object);
 
 #endif
index 28037e7a2d277e8a7a134cdbb0c6c0987ed27f60..429df427399a2607346103eba7ae15d063a966b1 100644 (file)
@@ -60,7 +60,6 @@ typedef struct thread thread_t;
 struct process
 {
     object_t header;
-    list_entry_t list;
     dword_t pid;
     char *name;
     memory_address_space_t memory_space;
index fd3c0de7af808f4918c1f5861704754b4de2ffd1..19f35774285b2446bfcadebe3491d23244f53fe5 100644 (file)
@@ -29,6 +29,7 @@ extern void pipe_cleanup(object_t*);
 static lock_t obj_lock = 0;
 static DECLARE_LIST(anonymous_objects);
 static DECLARE_LIST_ARRAY(named_objects, 256);
+static DECLARE_LIST_ARRAY(objects_by_type, 7);
 static object_cleanup_proc_t cleanup_procedures[OBJECT_TYPE_MAX] =
 {
     file_cleanup,
@@ -91,7 +92,13 @@ void dereference(object_t *object)
 {
     acquire_lock(&obj_lock);
     dword_t ref_count = --object->ref_count;
-    if (!ref_count) list_remove(&object->list);
+    
+    if (!ref_count)
+    {
+        list_remove(&object->by_name_list);
+        list_remove(&object->by_type_list);
+    }
+    
     release_lock(&obj_lock);
 
     if (!ref_count)
@@ -132,7 +139,7 @@ bool_t reference_by_name(const char *name, object_type_t type, object_t **object
 
     for (ptr = named_objects[hash].next; ptr != &named_objects[hash]; ptr = ptr->next)
     {
-        object_t *obj = CONTAINER_OF(ptr, object_t, list);
+        object_t *obj = CONTAINER_OF(ptr, object_t, by_name_list);
         
         if ((obj->name != NULL) && (strcmp(obj->name, name) == 0) && (obj->type == type))
         {
@@ -164,8 +171,9 @@ dword_t create_object(object_t *obj)
     obj->open_count = 0;
 
     acquire_lock(&obj_lock);
-    if (obj->name) list_append(&named_objects[get_name_hash(obj->name)], &obj->list);
-    else list_append(&anonymous_objects, &obj->list);
+    if (obj->name) list_append(&named_objects[get_name_hash(obj->name)], &obj->by_name_list);
+    else list_append(&anonymous_objects, &obj->by_name_list);
+    list_append(&objects_by_type[obj->type], &obj->by_type_list);
     release_lock(&obj_lock);
 
     return ERR_SUCCESS;
@@ -226,7 +234,8 @@ void close_object_internal(object_t *obj)
     if (!ref_count)
     {
         ASSERT(obj->open_count == 0);
-        list_remove(&obj->list);
+        list_remove(&obj->by_name_list);
+        list_remove(&obj->by_type_list);
     }
 
     release_lock(&obj_lock);
@@ -410,3 +419,25 @@ dword_t duplicate_handle(handle_t source_process, handle_t handle, handle_t dest
 
     return ret;
 }
+
+dword_t enum_objects_by_type(object_type_t type, object_t **object)
+{
+    list_entry_t *ptr;
+    acquire_lock(&obj_lock);
+    
+    if (*object == NULL) ptr = objects_by_type[type].next;
+    else ptr = (*object)->by_type_list.next;
+    
+    if (ptr == &objects_by_type[type])
+    {
+        release_lock(&obj_lock);
+        return ERR_NOMORE;
+    }
+
+    dereference(*object);
+    *object = CONTAINER_OF(ptr, object_t, by_type_list);
+    reference(*object);
+
+    release_lock(&obj_lock);
+    return ERR_SUCCESS;
+}
index 3c18729849d45891b02d9b673790f5be395b7af2..ce508a9a12def1578321d5b13ffe9867e96f36bc 100644 (file)
@@ -37,8 +37,6 @@ static loader_proc loaders[] =
 };
 
 process_t *kernel_process;
-DECLARE_LIST(process_list);
-resource_t proc_list_res = 0;
 
 static dword_t alloc_pid()
 {
@@ -66,10 +64,6 @@ void destroy_process(process_t *proc)
     int i;
     proc->terminating = TRUE;
 
-    acquire_resource_exclusive(&proc_list_res);
-    list_remove(&proc->list);
-    release_resource(&proc_list_res);
-
     delete_address_space(&proc->memory_space);
 
     acquire_resource_exclusive(&proc->handle_table_res);
@@ -111,19 +105,21 @@ process_t *get_current_process()
 
 dword_t open_process(dword_t pid, handle_t *handle)
 {
-    dword_t ret = ret = ERR_NOTFOUND;;
-    list_entry_t *ptr;
+    dword_t ret;
     process_t *proc = NULL;
 
-    acquire_resource_shared(&proc_list_res);
+    ret = enum_objects_by_type(OBJECT_PROCESS, (object_t**)&proc);
+    if (ret != ERR_NOMORE) return ret;
 
-    for (ptr = process_list.next; ptr != &process_list; ptr = ptr->next)
+    while (ret == ERR_SUCCESS)
     {
-        proc = CONTAINER_OF(ptr, process_t, list);
         if (proc->pid == pid) break;
+        ret = enum_objects_by_type(OBJECT_PROCESS, (object_t**)&proc);
     }
 
-    if (ptr != &process_list)
+    if (ret == ERR_NOMORE) ret = ERR_NOTFOUND;
+
+    if (ret == ERR_SUCCESS)
     {
         if (proc->current_user->uid == get_user_id() || check_privileges(PRIVILEGE_PROCESS_CONTROL))
         {
@@ -135,7 +131,6 @@ dword_t open_process(dword_t pid, handle_t *handle)
         }
     }
 
-    release_resource(&proc_list_res);
     return ret;
 }
 
@@ -265,10 +260,6 @@ dword_t create_process(const char *path, dword_t flags, process_params_t *parame
     ret = create_object(&proc->header);
     if (ret != ERR_SUCCESS) goto cleanup;
 
-    acquire_resource_exclusive(&proc_list_res);
-    list_append(&process_list, &proc->list);
-    release_resource(&proc_list_res);
-
     object_created = TRUE;
 
     thread_state_t initial_state;
@@ -591,7 +582,6 @@ dword_t query_process(handle_t handle, process_info_t info_type, void *buffer, d
 dword_t enum_processes(dword_t *pid_array, dword_t *count)
 {
     dword_t ret = ERR_SUCCESS;
-    list_entry_t *i;
     dword_t safe_count;
     dword_t cnt = 0;
 
@@ -614,9 +604,10 @@ dword_t enum_processes(dword_t *pid_array, dword_t *count)
         safe_count = *count;
     }
 
-    acquire_resource_shared(&proc_list_res);
+    process_t *proc = NULL;
+    ret = enum_objects_by_type(OBJECT_PROCESS, (object_t**)&proc);
 
-    for (i = process_list.next; i != &process_list; i = i->next)
+    while (ret == ERR_SUCCESS)
     {
         if (cnt == safe_count)
         {
@@ -624,8 +615,6 @@ dword_t enum_processes(dword_t *pid_array, dword_t *count)
             break;
         }
 
-        process_t *proc = CONTAINER_OF(i, process_t, list);
-
         EH_TRY
         {
             pid_array[cnt++] = proc->pid;
@@ -636,9 +625,11 @@ dword_t enum_processes(dword_t *pid_array, dword_t *count)
             EH_ESCAPE(break);
         }
         EH_DONE;
+
+        ret = enum_objects_by_type(OBJECT_PROCESS, (object_t**)&proc);
     }
 
-    release_resource(&proc_list_res);
+    if (ret == ERR_NOMORE) ret = ERR_SUCCESS;
 
 cleanup:
     EH_TRY *count = cnt;
@@ -716,6 +707,4 @@ void process_init(char *root_directory)
     kernel_process->handle_table_size = STARTUP_HANDLE_TABLE_SIZE;
     kernel_process->handle_count = 0;
     kernel_process->handle_table_res = 0;
-
-    list_append(&process_list, &kernel_process->list);
 }
index 945e37dcb446230fedc1536e279e6cb55dad3d9f..7d85cd43e79c08ca5358fbbfc38719c56c1e64be 100644 (file)
@@ -183,6 +183,7 @@ dword_t create_thread_internal(process_t *proc, thread_state_t *initial_state, d
     thread->owner_process = proc;
     thread->exit_code = 0;
     thread->terminated = FALSE;
+    thread->cancel_io = FALSE;
     thread->syscall_lock = 0;
     thread->wait_condition = WAIT_NEVER;
     thread->wait_timestamp = 0ULL;
index d6851238daf6a7b947caf018671bbc7ba27da053..7d38f00b16eca34fda6ff13bdc6c3a4b0fb83cc2 100644 (file)
@@ -244,22 +244,22 @@ dword_t create_user(dword_t uid, const char *name, dword_t *password_hash, qword
 
 dword_t delete_user(dword_t uid)
 {
-    list_entry_t *ptr;
-    if (get_previous_mode() == USER_MODE && !check_privileges(PRIVILEGE_MANAGE_USERS)) return ERR_FORBIDDEN;
+    if (get_previous_mode() == USER_MODE && !check_privileges(PRIVILEGE_MANAGE_USERS))
+    {
+        return ERR_FORBIDDEN;
+    }
 
-    acquire_resource_shared(&proc_list_res);
+    process_t *proc = NULL;
+    dword_t ret = enum_objects_by_type(OBJECT_PROCESS, (object_t**)&proc);
+    if (ret != ERR_NOMORE) return ret;
 
-    for (ptr = process_list.next; ptr != &process_list; ptr = ptr->next)
+    while (ret == ERR_SUCCESS)
     {
-        process_t *proc = CONTAINER_OF(ptr, process_t, list);
-        if (proc->current_user->uid == uid || proc->original_user->uid == uid)
-        {
-            release_resource(&proc_list_res);
-            return ERR_BUSY;
-        }
+        if (proc->current_user->uid == uid || proc->original_user->uid == uid) return ERR_BUSY;
+        ret = enum_objects_by_type(OBJECT_PROCESS, (object_t**)&proc);
     }
-
-    release_resource(&proc_list_res);
+    
+    if (ret != ERR_NOMORE) return ret;
 
     acquire_resource_exclusive(&user_list_res);
     user_t *user = get_user(uid);