📄 objwait.c
字号:
/* * objwait.c * * Copyright (C) 2006 Insigme Co., Ltd * * Authors: * - Chenzhan Hu, Lixing Chu, Limin Jin, Liwei Zhou, Zhiqiang Jiao * * This software has been developed while working on the Linux Unified Kernel * project (http://linux.insigma.com.cn) in the Insigma Reaserch Institute, * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn). * * The project is sponsored by Insigma Co., Ltd. * * The authors can be reached at linux@insigma.com.cn. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * Revision History: * Jan 2006 - Created. */ /* * objwait.c: syscall NtWaitForMultipleObjects * Reference to Kernel-win32 code */#include <linux/module.h>#include "object.h"#include "objwait.h"#include "thread.h"#include <asm/uaccess.h>#ifdef CONFIG_UNIFIED_KERNEL/* * wait for multiple objects * - returns: * - WAIT_OBJECT_0 + index of the signalled object [signalled okay] * - WAIT_ABANDONED_0 + index of the signalled object [object unavailable] * - WAIT_TIMEOUT [timeout] * - -ve [error] */int do_wait_for_objects(struct ethread *thread, struct wait_table *wt, long *timeout){ struct wait_table_entry *wte; int state, retval; for (wte=wt->wt_entries; wte<wt->wt_last; wte++) wte->wte_data = 0; retval = STATUS_TIMEOUT; for (;;) { set_current_state(TASK_INTERRUPTIBLE); for (wte=wt->wt_entries; wte<wt->wt_last; wte++) { state = wte->wte_obj->o_class->poll(wte,thread); switch (state) { case POLL_NOTSIG: break; case POLL_SIG: retval = STATUS_WAIT_0 + (wte - wt->wt_entries); goto done; default: if (state<0) { retval = state; /* error */ goto done; } retval = STATUS_ABANDONED_WAIT_0 + (wte - wt->wt_entries); goto done; } } if (signal_pending(current)) { retval = -ERESTARTSYS; goto done; } if (!*timeout) break; *timeout = schedule_timeout(*timeout); } done: current->state = TASK_RUNNING; return retval;} /* end do_wait_for_objects() *//* * Win32 system call * wait for one of a set of objects to become signalled */NTSTATUS STDCALLNtWaitForMultipleObjects(IN ULONG ObjectCount, IN PHANDLE ObjectsArray, IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL){ struct wait_table_entry *wte; struct wait_table *wt; struct ethread *thread; long long _timeout; long timeout; int i; NTSTATUS Status; thread = thread_find(); ktrace("NtWaitForMultipleObjects\n"); if(!thread) return -EINVAL; if (copy_from_user(&_timeout, TimeOut, sizeof(_timeout))) return -EFAULT; timeout = (long) _timeout; /* mustn't exceed the maximum handle count */ if (ObjectCount<=0 || ObjectCount>MAXIMUM_WAIT_OBJECTS) return -EINVAL; if ((unsigned long)timeout==0xFFFFFFFF /* INFINITE */) { timeout = MAX_SCHEDULE_TIMEOUT; } else if (timeout) { /* Careful about overflow in the intermediate values */ if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ) timeout = (unsigned long)(timeout*HZ+999)/1000+1; else /* Negative or overflow */ timeout = MAX_SCHEDULE_TIMEOUT; } /* set up the wait table */ wt = (struct wait_table *) __get_free_page(GFP_KERNEL); if (!wt) return -ENOMEM; wt->wt_last = wt->wt_entries; /* load all the handles */ for (i=0; i<ObjectCount; i++) { HANDLE handle; win32_object *obj; Status = get_user(handle,(PHANDLE) &ObjectsArray[i]); if (Status<0) goto cleanup; obj = GetObject(thread,handle,NULL); if (IS_ERR(obj)) { Status = PTR_ERR(obj); goto cleanup; } wte = wt->wt_last; wt->wt_last++; wte->wte_obj = obj; init_waitqueue_entry(&wte->wte_wait,current); add_wait_queue(&obj->o_wait,&wte->wte_wait); } /* actually do the deed */ Status = do_wait_for_objects(thread,wt,&timeout); /* reconstitute the timeout in userspace */ if (timeout==MAX_SCHEDULE_TIMEOUT) _timeout = 0xFFFFFFFF /* INFINITE */; else { timeout = ((timeout-1) * 1000 + HZ - 1) / HZ; _timeout = timeout<0 ? 0 : timeout; } if(copy_to_user(TimeOut, &_timeout, sizeof(_timeout))) Status = -EFAULT; cleanup: /* clean up the wait table */ wte = wt->wt_last; do { wte--; remove_wait_queue(&wte->wte_obj->o_wait,&wte->wte_wait); objput(wte->wte_obj); } while (wte>wt->wt_entries); free_page((unsigned long) wt); return Status;} /* end NtWaitForMultipleObjects() */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -