HelenOS sources
This source file includes following definitions.
- system_open
- system_close
- system_callback_create
- system_shutdown
- system_shutdown_complete
- system_shutdown_failed
- system_cb_conn
#include <async.h>
#include <assert.h>
#include <system.h>
#include <errno.h>
#include <fibril_synch.h>
#include <ipc/system.h>
#include <loc.h>
#include <stdlib.h>
#include "../private/system.h"
static errno_t system_callback_create(system_t *);
static void system_cb_conn(ipc_call_t *, void *);
errno_t system_open(const char *svcname, system_cb_t *cb, void *arg,
system_t **rsystem)
{
service_id_t system_svc;
async_sess_t *sess;
system_t *system;
errno_t rc;
system = calloc(1, sizeof(system_t));
if (system == NULL)
return ENOMEM;
fibril_mutex_initialize(&system->lock);
fibril_condvar_initialize(&system->cv);
rc = loc_service_get_id(svcname, &system_svc, IPC_FLAG_BLOCKING);
if (rc != EOK)
goto error;
sess = loc_service_connect(system_svc, INTERFACE_SYSTEM,
IPC_FLAG_BLOCKING);
if (sess == NULL)
goto error;
system->sess = sess;
system->cb = cb;
system->cb_arg = arg;
rc = system_callback_create(system);
if (rc != EOK) {
async_hangup(sess);
goto error;
}
*rsystem = system;
return EOK;
error:
free(system);
return rc;
}
void system_close(system_t *system)
{
fibril_mutex_lock(&system->lock);
async_hangup(system->sess);
system->sess = NULL;
while (!system->cb_done)
fibril_condvar_wait(&system->cv, &system->lock);
fibril_mutex_unlock(&system->lock);
free(system);
}
static errno_t system_callback_create(system_t *system)
{
async_exch_t *exch = async_exchange_begin(system->sess);
aid_t req = async_send_0(exch, SYSTEM_CALLBACK_CREATE, NULL);
port_id_t port;
errno_t rc = async_create_callback_port(exch, INTERFACE_SYSTEM_CB, 0, 0,
system_cb_conn, system, &port);
async_exchange_end(exch);
if (rc != EOK)
return rc;
errno_t retval;
async_wait_for(req, &retval);
return retval;
}
errno_t system_shutdown(system_t *system)
{
async_exch_t *exch = async_exchange_begin(system->sess);
errno_t rc = async_req_0_0(exch, SYSTEM_SHUTDOWN);
async_exchange_end(exch);
return rc;
}
static void system_shutdown_complete(system_t *system, ipc_call_t *icall)
{
if (system->cb != NULL && system->cb->shutdown_complete != NULL)
system->cb->shutdown_complete(system->cb_arg);
async_answer_0(icall, EOK);
}
static void system_shutdown_failed(system_t *system, ipc_call_t *icall)
{
if (system->cb != NULL && system->cb->shutdown_complete != NULL)
system->cb->shutdown_failed(system->cb_arg);
async_answer_0(icall, EOK);
}
static void system_cb_conn(ipc_call_t *icall, void *arg)
{
system_t *system = (system_t *) arg;
while (true) {
ipc_call_t call;
async_get_call(&call);
if (!ipc_get_imethod(&call)) {
async_answer_0(&call, EOK);
goto out;
}
switch (ipc_get_imethod(&call)) {
case SYSTEM_SHUTDOWN_COMPLETE:
system_shutdown_complete(system, &call);
break;
case SYSTEM_SHUTDOWN_FAILED:
system_shutdown_failed(system, &call);
break;
default:
async_answer_0(&call, ENOTSUP);
break;
}
}
out:
fibril_mutex_lock(&system->lock);
system->cb_done = true;
fibril_mutex_unlock(&system->lock);
fibril_condvar_broadcast(&system->cv);
}
HelenOS homepage, sources at GitHub