示例#1
0
文件: fifo.cpp 项目: mylegacy/haiku
status_t
Inode::Select(uint8 event, selectsync* sync, int openMode)
{
	bool writer = true;
	select_sync_pool** pool;
	if ((openMode & O_RWMASK) == O_RDONLY) {
		pool = &fReadSelectSyncPool;
		writer = false;
	} else if ((openMode & O_RWMASK) == O_WRONLY) {
		pool = &fWriteSelectSyncPool;
	} else
		return B_NOT_ALLOWED;

	if (add_select_sync_pool_entry(pool, sync, event) != B_OK)
		return B_ERROR;

	// signal right away, if the condition holds already
	if (writer) {
		if ((event == B_SELECT_WRITE
				&& (fBuffer.Writable() > 0 || fReaderCount == 0))
			|| (event == B_SELECT_ERROR && fReaderCount == 0)) {
			return notify_select_event(sync, event);
		}
	} else {
		if (event == B_SELECT_READ
				&& (fBuffer.Readable() > 0 || fWriterCount == 0)) {
			return notify_select_event(sync, event);
		}
	}

	return B_OK;
}
示例#2
0
// _HandleRequest
status_t
KernelRequestHandler::_HandleRequest(NotifySelectEventRequest* request)
{
	// check and execute the request
	status_t result = B_OK;
	if (fFileSystem->KnowsSelectSyncEntry(request->sync)) {
		if (request->unspecifiedEvent) {
			// old style add-ons can't provide an event argument; we shoot
			// all events
			notify_select_event(request->sync, B_SELECT_READ);
			notify_select_event(request->sync, B_SELECT_WRITE);
			notify_select_event(request->sync, B_SELECT_ERROR);
		} else {
			PRINT(("notify_select_event(%p, %d)\n", request->sync,
				(int)request->event));
			notify_select_event(request->sync, request->event);
		}
	} else
		result = B_BAD_VALUE;

	// prepare the reply
	RequestAllocator allocator(fPort->GetPort());
	NotifySelectEventReply* reply;
	status_t error = AllocateRequest(allocator, &reply);
	if (error != B_OK)
		return error;

	reply->error = result;

	// send the reply
	return fPort->SendRequest(&allocator);
}
示例#3
0
void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
{
    LogFlow((MODULE_NAME "::NativeISRMousePollEvent:\n"));

    status_t err = B_OK;
    //dprintf(MODULE_NAME ": isr mouse\n");

    /*
     * Wake up poll waiters.
     */
    //selwakeup(&g_SelInfo);
    //XXX:notify_select_event();
    RTSpinlockAcquire(g_Spinlock);

    if (sState.selectSync)
    {
        //dprintf(MODULE_NAME ": isr mouse: notify\n");
        notify_select_event(sState.selectSync, sState.selectEvent);
        sState.selectEvent = (uint8_t)0;
        sState.selectRef = (uint32_t)0;
        sState.selectSync = NULL;
    }
    else
        err = B_ERROR;

    RTSpinlockRelease(g_Spinlock);
}
示例#4
0
/**
 * Driver select hook.
 *
 * @param cookie        The session.
 * @param event         The event.
 * @param ref           ???
 * @param sync          ???
 *
 * @return Haiku status code.
 */
static status_t vgdrvHaikuSelect(void *cookie, uint8 event, uint32 ref, selectsync *sync)
{
    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
    status_t err = B_OK;

    switch (event)
    {
        case B_SELECT_READ:
            break;
        default:
            return EINVAL;
    }

    RTSpinlockAcquire(g_DevExt.SessionSpinlock);

    uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
    if (pSession->u32MousePosChangedSeq != u32CurSeq)
    {
        pSession->u32MousePosChangedSeq = u32CurSeq;
        notify_select_event(sync, event);
    }
    else if (sState.selectSync == NULL)
    {
        sState.selectEvent = (uint8_t)event;
        sState.selectRef = (uint32_t)ref;
        sState.selectSync = (void *)sync;
    }
    else
        err = B_WOULD_BLOCK;

    RTSpinlockRelease(g_DevExt.SessionSpinlock);

    return err;
}
status_t
socket_request_notification(net_socket* _socket, uint8 event, selectsync* sync)
{
	net_socket_private* socket = (net_socket_private*)_socket;

	mutex_lock(&socket->lock);

	status_t status = add_select_sync_pool_entry(&socket->select_pool, sync,
		event);

	mutex_unlock(&socket->lock);

	if (status != B_OK)
		return status;

	// check if the event is already present
	// TODO: add support for poll() types

	switch (event) {
		case B_SELECT_READ:
		{
			ssize_t available = socket_read_avail(socket);
			if ((ssize_t)socket->receive.low_water_mark <= available
				|| available < B_OK)
				notify_select_event(sync, event);
			break;
		}
		case B_SELECT_WRITE:
		{
			ssize_t available = socket_send_avail(socket);
			if ((ssize_t)socket->send.low_water_mark <= available
				|| available < B_OK)
				notify_select_event(sync, event);
			break;
		}
		case B_SELECT_ERROR:
			// TODO: B_SELECT_ERROR condition!
			break;
	}

	return B_OK;
}
示例#6
0
/**
 * Driver close hook.
 * @param cookie        The session.
 *
 * @return Haiku status code.
 */
static status_t vgdrvHaikuClose(void *cookie)
{
    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
    Log(("vgdrvHaikuClose: pSession=%p\n", pSession));

    /** @todo r=ramshankar: should we really be using the session spinlock here? */
    RTSpinlockAcquire(g_DevExt.SessionSpinlock);

    /** @todo we don't know if it belongs to this session!! */
    if (sState.selectSync)
    {
        //dprintf(DRIVER_NAME "close: unblocking select %p %x\n", sState.selectSync, sState.selectEvent);
        notify_select_event(sState.selectSync, sState.selectEvent);
        sState.selectEvent = (uint8_t)0;
        sState.selectRef = (uint32_t)0;
        sState.selectSync = (void *)NULL;
    }

    RTSpinlockRelease(g_DevExt.SessionSpinlock);
    return B_OK;
}