예제 #1
0
파일: wait.c 프로젝트: amir9/longene
NTSTATUS SERVICECALL
NtWaitForSingleObject(IN HANDLE ObjectHandle,
		IN BOOLEAN Alertable,
		IN PLARGE_INTEGER TimeOut OPTIONAL)
{
	PVOID object;
	LARGE_INTEGER _timeout;
	MODE previous_mode;
	NTSTATUS status;

	ktrace("ObjectHandle %p, Alertable %d\n", ObjectHandle, Alertable);
	previous_mode = (unsigned long)TimeOut > TASK_SIZE ? KernelMode : UserMode;
	if(TimeOut){
		if (previous_mode == UserRequest) {
			if (copy_from_user(&_timeout, TimeOut, sizeof(_timeout)))
				return STATUS_NO_MEMORY;
		} else
			_timeout = *TimeOut;
	}

	status = ref_object_by_handle(ObjectHandle,
				SYNCHRONIZE,
				NULL,
				KernelMode,
				&object,
				NULL);
	if (!NT_SUCCESS(status))
		return status;

	if(TimeOut){
		status = wait_for_single_object(object,
				UserRequest,
				KernelMode,
				Alertable,
				&_timeout);
	} else {
		status = wait_for_single_object(object,
				UserRequest,
				KernelMode,
				Alertable,
				NULL);
	}	
	       	
	if (!NT_SUCCESS(status))
		goto out;

	if (previous_mode == UserMode) {
		if (copy_to_user(TimeOut, &_timeout, sizeof(_timeout))) {
			status = STATUS_NO_MEMORY;
			goto out;
		}
	}
	else
		*TimeOut = _timeout;

out:
	deref_object(object);
	return status;
} /* end NtWaitForSingleObject */
예제 #2
0
파일: mutex.cpp 프로젝트: qiutaoleo/hpx
    bool mutex::timed_lock(::boost::system_time const& wait_until)
    {
        HPX_ITT_SYNC_PREPARE(this);
        if (try_lock_internal()) {
            HPX_ITT_SYNC_ACQUIRED(this);
            util::register_lock(this);
            return true;
        }

        boost::uint32_t old_count =
            active_count_.load(boost::memory_order_acquire);
        mark_waiting_and_try_lock(old_count);

        if (old_count & lock_flag_value)
        {
            // wait for lock to get available
            bool lock_acquired = false;
            do {
                if (wait_for_single_object(wait_until))
                {
                    // if this timed out, just return false
                    --active_count_;
                    HPX_ITT_SYNC_CANCEL(this);
                    return false;
                }
                clear_waiting_and_try_lock(old_count);
                lock_acquired = !(old_count & lock_flag_value);
            } while (!lock_acquired);
        }
        HPX_ITT_SYNC_ACQUIRED(this);
        util::register_lock(this);
        return true;
    }
예제 #3
0
VOID
acquire_fmutex_unsafe(PFAST_MUTEX FastMutex)
{
	atomic_inc(&FastMutex->Contention);
	while (xchg(&FastMutex->Count, 0) == 0)
		wait_for_single_object(&FastMutex->Event,
				Executive,
				KernelMode,
				FALSE,
				NULL);
	atomic_dec(&FastMutex->Contention);
	FastMutex->Owner = (struct kthread *)get_current_ethread(); 
}
예제 #4
0
bool Thread::wait(unsigned wait_time) {
  return wait_for_single_object(h_thread, wait_time);
}
예제 #5
0
파일: wait.c 프로젝트: amir9/longene
NTSTATUS SERVICECALL
NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
		IN HANDLE WaitableObjectHandle,
		IN BOOLEAN Alertable,
		IN PLARGE_INTEGER TimeOut OPTIONAL)
{
	PVOID signal_obj, wait_obj;
	struct dispatcher_header *signal_header;
	LARGE_INTEGER _timeout;
	MODE previous_mode;
	NTSTATUS status;

	ktrace("ObjectHandleToSignal %p, WaitableObjectHandle %p, Alertable %d\n",
			ObjectHandleToSignal, WaitableObjectHandle, Alertable);
	previous_mode = (unsigned long)TimeOut > TASK_SIZE ? KernelMode : UserMode;
	if(TimeOut){
		if (previous_mode == UserMode) {
			if (copy_from_user(&_timeout, TimeOut, sizeof(_timeout)))
				return STATUS_NO_MEMORY;
		} else
			_timeout = *TimeOut;
	}

	status = ref_object_by_handle(ObjectHandleToSignal, 0,
			NULL, KernelMode, &signal_obj, NULL);
	if (!NT_SUCCESS(status))
		return status;

	status = ref_object_by_handle(WaitableObjectHandle, SYNCHRONIZE,
			NULL, KernelMode, &wait_obj, NULL);
	if (!NT_SUCCESS(status)) {
		deref_object(signal_obj);
		return status;
	}

	signal_header = (struct dispatcher_header *)signal_obj;

	if (is_wine_object(signal_header->type)) {
		struct object *obj = (struct object*)signal_obj;
		unsigned int access = get_handle_access(process2eprocess(current_thread->process), WaitableObjectHandle);
		if (BODY_TO_HEADER(obj)->ops->signal)
			BODY_TO_HEADER(obj)->ops->signal(obj, access);
	}
	else
		switch (signal_header->type) {
			case EventNotificationObject:
			case EventSynchronizationObject:
				set_event(signal_obj, EVENT_INCREMENT, TRUE);
				break;

			case MutantObject:
				release_mutant(signal_obj, IO_NO_INCREMENT, FALSE, TRUE);
				break;

			case SemaphoreObject:
				release_semaphore(signal_obj, SEMAPHORE_INCREMENT, 1, TRUE);
				break;

			default:
				deref_object(signal_obj);
				deref_object(wait_obj);
				return STATUS_OBJECT_TYPE_MISMATCH;
		}

	if(TimeOut){
		status = wait_for_single_object(wait_obj,
				UserRequest, KernelMode, Alertable, &_timeout);
	} else {
		status = wait_for_single_object(wait_obj,
				UserRequest, KernelMode, Alertable, NULL);
	}	

	if (!NT_SUCCESS(status))
		goto out;

	if (TimeOut) {
		if (previous_mode == UserMode) {
			if (copy_to_user(TimeOut, &_timeout, sizeof(_timeout))) {
				status = STATUS_NO_MEMORY;
				goto out;
			}
		} else
			*TimeOut = _timeout;
	}

out:
	deref_object(signal_obj);
	deref_object(wait_obj);

	return status;
} /* end NtSignalAndWaitForSingleObject */