/*
 * Init function
 */
 errval_t arrakis_rpc_client_init(struct arrakis_rpc_client *rpc, struct arrakis_binding *binding)
{
    errval_t _err;
    
    // Setup state of RPC client object
    rpc->b = binding;
    rpc->reply_present = false;
    rpc->rpc_in_progress = false;
    rpc->async_error = SYS_ERR_OK;
    waitset_init(&(rpc->rpc_waitset));
    flounder_support_waitset_chanstate_init(&(rpc->dummy_chanstate));
    rpc->vtbl = arrakis_rpc_vtbl;
    binding->st = rpc;
    
    // Change waitset on binding
    _err = ((binding->change_waitset)(binding, &(rpc->rpc_waitset)));
    if (err_is_fail(_err)) {
        waitset_destroy(&(rpc->rpc_waitset));
        return(err_push(_err, FLOUNDER_ERR_CHANGE_WAITSET));
    }
    
    // Set RX handlers on binding object for RPCs
    (binding->rx_vtbl).spawn_arrakis_domain_response = arrakis_spawn_arrakis_domain__rpc_rx_handler;
    
    // Set error handler on binding object
    binding->error_handler = arrakis_rpc_client_error;
    
    return(SYS_ERR_OK);
}
/*
 * Init function
 */
 errval_t usb_manager_rpc_client_init(struct usb_manager_rpc_client *rpc, struct usb_manager_binding *binding)
{
    errval_t _err;
    
    // Setup state of RPC client object
    rpc->b = binding;
    rpc->reply_present = false;
    rpc->rpc_in_progress = false;
    rpc->async_error = SYS_ERR_OK;
    waitset_init(&(rpc->rpc_waitset));
    flounder_support_waitset_chanstate_init(&(rpc->dummy_chanstate));
    rpc->vtbl = usb_manager_rpc_vtbl;
    binding->st = rpc;
    
    // Change waitset on binding
    _err = ((binding->change_waitset)(binding, &(rpc->rpc_waitset)));
    if (err_is_fail(_err)) {
        waitset_destroy(&(rpc->rpc_waitset));
        return(err_push(_err, FLOUNDER_ERR_CHANGE_WAITSET));
    }
    
    // Set RX handlers on binding object for RPCs
    (binding->rx_vtbl).connect_response = usb_manager_connect__rpc_rx_handler;
    (binding->rx_vtbl).device_disconnect_notify_response = usb_manager_device_disconnect_notify__rpc_rx_handler;
    (binding->rx_vtbl).request_read_response = usb_manager_request_read__rpc_rx_handler;
    (binding->rx_vtbl).request_write_response = usb_manager_request_write__rpc_rx_handler;
    (binding->rx_vtbl).request_response = usb_manager_request__rpc_rx_handler;
    (binding->rx_vtbl).transfer_setup_response = usb_manager_transfer_setup__rpc_rx_handler;
    (binding->rx_vtbl).transfer_unsetup_response = usb_manager_transfer_unsetup__rpc_rx_handler;
    (binding->rx_vtbl).transfer_start_response = usb_manager_transfer_start__rpc_rx_handler;
    (binding->rx_vtbl).transfer_stop_response = usb_manager_transfer_stop__rpc_rx_handler;
    (binding->rx_vtbl).transfer_status_response = usb_manager_transfer_status__rpc_rx_handler;
    (binding->rx_vtbl).transfer_state_response = usb_manager_transfer_state__rpc_rx_handler;
    (binding->rx_vtbl).transfer_clear_stall_response = usb_manager_transfer_clear_stall__rpc_rx_handler;
    (binding->rx_vtbl).transfer_done_notify_response = usb_manager_transfer_done_notify__rpc_rx_handler;
    (binding->rx_vtbl).device_get_speed_response = usb_manager_device_get_speed__rpc_rx_handler;
    (binding->rx_vtbl).device_get_state_response = usb_manager_device_get_state__rpc_rx_handler;
    (binding->rx_vtbl).device_suspend_response = usb_manager_device_suspend__rpc_rx_handler;
    (binding->rx_vtbl).device_resume_response = usb_manager_device_resume__rpc_rx_handler;
    (binding->rx_vtbl).device_powersave_response = usb_manager_device_powersave__rpc_rx_handler;
    
    // Set error handler on binding object
    binding->error_handler = usb_manager_rpc_client_error;
    
    return(SYS_ERR_OK);
}
/*
 * Init function
 */
 errval_t acpi_rpc_client_init(struct acpi_rpc_client *rpc, struct acpi_binding *binding)
{
    errval_t _err;
    
    // Setup state of RPC client object
    rpc->b = binding;
    rpc->reply_present = false;
    rpc->rpc_in_progress = false;
    rpc->async_error = SYS_ERR_OK;
    waitset_init(&(rpc->rpc_waitset));
    flounder_support_waitset_chanstate_init(&(rpc->dummy_chanstate));
    rpc->vtbl = acpi_rpc_vtbl;
    binding->st = rpc;
    
    // Change waitset on binding
    _err = ((binding->change_waitset)(binding, &(rpc->rpc_waitset)));
    if (err_is_fail(_err)) {
        waitset_destroy(&(rpc->rpc_waitset));
        return(err_push(_err, FLOUNDER_ERR_CHANGE_WAITSET));
    }
    
    // Set RX handlers on binding object for RPCs
    (binding->rx_vtbl).get_pcie_confspace_response = acpi_get_pcie_confspace__rpc_rx_handler;
    (binding->rx_vtbl).read_irq_table_response = acpi_read_irq_table__rpc_rx_handler;
    (binding->rx_vtbl).set_device_irq_response = acpi_set_device_irq__rpc_rx_handler;
    (binding->rx_vtbl).enable_and_route_interrupt_response = acpi_enable_and_route_interrupt__rpc_rx_handler;
    (binding->rx_vtbl).reset_response = acpi_reset__rpc_rx_handler;
    (binding->rx_vtbl).sleep_response = acpi_sleep__rpc_rx_handler;
    (binding->rx_vtbl).get_vbe_bios_cap_response = acpi_get_vbe_bios_cap__rpc_rx_handler;
    (binding->rx_vtbl).mm_alloc_range_proxy_response = acpi_mm_alloc_range_proxy__rpc_rx_handler;
    (binding->rx_vtbl).mm_realloc_range_proxy_response = acpi_mm_realloc_range_proxy__rpc_rx_handler;
    (binding->rx_vtbl).mm_free_proxy_response = acpi_mm_free_proxy__rpc_rx_handler;
    
    // Set error handler on binding object
    binding->error_handler = acpi_rpc_client_error;
    
    return(SYS_ERR_OK);
}
Ejemplo n.º 4
0
ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
    struct fdtab_entry *e = fdtab_get(sockfd);

    switch(e->type) {
    case FDTAB_TYPE_UNIX_SOCKET:
        {
            struct _unix_socket *us = e->handle;

            // XXX: Don't support flags
            assert(flags == 0);

            thread_mutex_lock(&us->mutex);

            if(us->passive
               || us->u.active.mode != _UNIX_SOCKET_MODE_CONNECTED) {
                errno = ENOTCONN;
                thread_mutex_unlock(&us->mutex);
                return -1;
            }

            if(us->recv_buf_valid == 0) {
                // No more data
                if(us->nonblocking) {
                    errno = EAGAIN;
                    thread_mutex_unlock(&us->mutex);
                    return -1;
                } else {
                    struct waitset ws;
                    errval_t err;

                    waitset_init(&ws);

                    err = us->u.active.binding->change_waitset
                        (us->u.active.binding, &ws);
                    if(err_is_fail(err)) {
                        USER_PANIC_ERR(err, "change_waitset");
                    }

                    while(us->recv_buf_valid == 0) {
                        err = event_dispatch(&ws);
                        if(err_is_fail(err)) {
                            USER_PANIC_ERR(err, "waitset_destroy");
                        }
                    }

                    // XXX: Assume it was on the default waitset
                    err = us->u.active.binding->change_waitset
                        (us->u.active.binding, get_default_waitset());
                    if(err_is_fail(err)) {
                        USER_PANIC_ERR(err, "change_waitset");
                    }

                    err = waitset_destroy(&ws);
                    if(err_is_fail(err)) {
                        USER_PANIC_ERR(err, "waitset_destroy");
                    }
                }
            }

            size_t recved = 0;
            while(recved < len && us->recv_list != NULL) {
                struct _unix_socket_recv *usr = us->recv_list;
                size_t consume = MIN(len - recved, usr->size - usr->consumed);

                memcpy(buf + recved, &usr->msg[usr->consumed], consume);
                usr->consumed += consume;
                us->recv_buf_valid -= consume;
                recved += consume;

                if(usr->consumed == usr->size) {
                    us->recv_list = usr->next;
                    if(us->recv_list == NULL) {
                        us->recv_list_end = NULL;
                    }
                    free(usr->msg);
                    free(usr);
                } else {
                    assert(recved == len);
                }
            }

            thread_mutex_unlock(&us->mutex);
            return recved;
        }

    case FDTAB_TYPE_LWIP_SOCKET:
        lwip_mutex_lock();
        ssize_t ret = lwip_recv(e->fd, buf, len, flags);
        lwip_mutex_unlock();
        return ret;

    case FDTAB_TYPE_AVAILABLE:
        errno = EBADF;
        return -1;

    default:
        errno = ENOTSOCK;
        return -1;
    }
}
Ejemplo n.º 5
0
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
{
    struct fdtab_entry *e = fdtab_get(sockfd);

    switch(e->type) {
    case FDTAB_TYPE_UNIX_SOCKET:
        {
            struct _unix_socket *us = e->handle;

            // XXX: Don't support flags
            assert(flags == 0);

            thread_mutex_lock(&us->mutex);

            if(us->passive
               || us->u.active.mode != _UNIX_SOCKET_MODE_CONNECTED) {
                errno = ENOTCONN;
                thread_mutex_unlock(&us->mutex);
                return -1;
            }

            if(us->send_buf != NULL) {
                if(us->nonblocking) {
                    errno = EAGAIN;
                    thread_mutex_unlock(&us->mutex);
                    return -1;
                } else {
                    assert(!"NYI");
                }
            }

            // Bleh. Gotta copy here. I can't just wait until the
            // message is fully sent, as that might block
            // indefinitely.
            us->send_buf = malloc(len);
            memcpy(us->send_buf, buf, len);

            struct event_closure ec = {
                .handler = unixsock_sent,
                .arg = us,
            };
            errval_t err = us->u.active.binding->tx_vtbl.
                send(us->u.active.binding, ec, us->send_buf, len);
            if(err_is_fail(err)) {
                USER_PANIC_ERR(err, "unixsock->send");
                thread_mutex_unlock(&us->mutex);
                return -1;
            }

            // Wait until all data sent if blocking
            if(!us->nonblocking) {
                struct waitset ws;
                waitset_init(&ws);

                err = us->u.active.binding->change_waitset
                    (us->u.active.binding, &ws);
                if(err_is_fail(err)) {
                    USER_PANIC_ERR(err, "change_waitset");
                }

                while(us->send_buf != NULL) {
                    err = event_dispatch(&ws);
                    if(err_is_fail(err)) {
                        USER_PANIC_ERR(err, "waitset_destroy");
                    }
                }

                // XXX: Assume it was on the default waitset
                err = us->u.active.binding->change_waitset
                    (us->u.active.binding, get_default_waitset());
                if(err_is_fail(err)) {
                    USER_PANIC_ERR(err, "change_waitset");
                }

                err = waitset_destroy(&ws);
                if(err_is_fail(err)) {
                    USER_PANIC_ERR(err, "waitset_destroy");
                }
            }

            // XXX: We send all or nothing
            thread_mutex_unlock(&us->mutex);
            return len;
        }

    case FDTAB_TYPE_LWIP_SOCKET:
        lwip_mutex_lock();
        ssize_t ret = lwip_send(e->fd, buf, len, flags);
        lwip_mutex_unlock();
        return ret;

    case FDTAB_TYPE_AVAILABLE:
        errno = EBADF;
        return -1;

    default:
        errno = ENOTSOCK;
        return -1;
    }
}