Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1406 → Rev 1407

/uspace/trunk/libc/include/async.h
2,6 → 2,7
#define _libc_ASYNC_H_
 
#include <ipc/ipc.h>
#include <psthread.h>
 
int async_manager(void);
void async_create_manager(void);
10,6 → 11,8
ipc_callid_t async_get_call(ipc_call_t *data);
 
/* Should be defined by application */
pstid_t async_new_connection(ipc_callid_t callid, ipc_call_t *call,
void (*cthread)(ipc_callid_t,ipc_call_t *));
void client_connection(ipc_callid_t callid, ipc_call_t *call) __attribute__((weak));
 
#endif
/uspace/trunk/libc/generic/thread.c
91,12 → 91,11
pt = psthread_setup();
__tcb_set(pt->tcb);
async_create_manager();
 
uarg->uspace_thread_function(uarg->uspace_thread_arg);
free(uarg->uspace_stack);
free(uarg);
 
/* If there is a manager, destroy it */
async_destroy_manager();
psthread_teardown(pt);
 
/uspace/trunk/libc/generic/psthread.c
35,6 → 35,7
#include <kernel/arch/faddr.h>
#include <futex.h>
#include <assert.h>
#include <async.h>
 
#ifndef PSTHREAD_INITIAL_STACK_PAGES_NO
#define PSTHREAD_INITIAL_STACK_PAGES_NO 1
134,7 → 135,9
if (ctype == PS_FROM_MANAGER && list_empty(&ready_list)) {
goto ret_0;
}
assert(!(ctype == PS_TO_MANAGER && list_empty(&manager_list)));
/* If we are going to manager and none exists, create it */
if (ctype == PS_TO_MANAGER && list_empty(&manager_list))
async_create_manager();
 
pt = __tcb_get()->pst_data;
if (!context_save(&pt->ctx))
250,7 → 253,6
{
futex_down(&psthread_futex);
if (list_empty(&manager_list)) {
printf("No manager found!.\n");
futex_up(&psthread_futex);
return;
}
/uspace/trunk/libc/generic/async.c
60,17 → 60,22
*
* 2) Multithreaded server application
* main() {
* wait_for_connection(new_connection);
* async_manager();
* }
*
*
* new_connection(int connection) {
* accept(connection);
* msg = get_msg();
* handle(msg);
* answer(msg);
* client_connection(icallid, *icall) {
* if (want_refuse) {
* ipc_answer_fast(icallid, ELIMIT, 0, 0);
* return;
* }
* ipc_answer_fast(icallid, 0, 0, 0);
*
* msg = get_msg();
* callid = async_get_call(&call);
* handle(callid, call);
* ipc_answer_fast(callid, 1,2,3);
*
* callid = async_get_call(&call);
* ....
* }
*
104,6 → 109,7
/* Structures for connection opening packet */
ipc_callid_t callid;
ipc_call_t call;
void (*cthread)(ipc_callid_t,ipc_call_t *);
} connection_t;
 
__thread connection_t *PS_connection;
225,7 → 231,7
 
/* Setup thread local connection pointer */
PS_connection = (connection_t *)arg;
client_connection(PS_connection->callid, &PS_connection->call);
PS_connection->cthread(PS_connection->callid, &PS_connection->call);
 
/* Remove myself from connection hash table */
futex_down(&conn_futex);
247,8 → 253,15
* structures and inserts it into the hash table, so that
* later we can easily do routing of messages to particular
* threads.
*
* @param callid Callid of the IPC_M_CONNECT_ME_TO packet
* @param call Call data of the opening packet
* @param cthread Thread function that should be called upon
* opening the connection
* @return New thread id
*/
static void new_connection(ipc_callid_t callid, ipc_call_t *call)
pstid_t async_new_connection(ipc_callid_t callid, ipc_call_t *call,
void (*cthread)(ipc_callid_t,ipc_call_t *))
{
pstid_t ptid;
connection_t *conn;
257,7 → 270,7
conn = malloc(sizeof(*conn));
if (!conn) {
ipc_answer_fast(callid, ENOMEM, 0, 0);
return;
return NULL;
}
conn->in_phone_hash = IPC_GET_ARG3(*call);
list_initialize(&conn->msg_queue);
265,11 → 278,12
conn->callid = callid;
conn->call = *call;
conn->active = 1; /* We will activate it asap */
conn->cthread = cthread;
list_initialize(&conn->link);
if (!conn->ptid) {
free(conn);
ipc_answer_fast(callid, ENOMEM, 0, 0);
return;
return NULL;
}
key = conn->in_phone_hash;
futex_down(&conn_futex);
278,6 → 292,8
futex_up(&conn_futex);
 
psthread_add_ready(conn->ptid);
 
return conn->ptid;
}
 
/** Handle call to a task */
291,7 → 307,7
break;
case IPC_M_CONNECT_ME_TO:
/* Open new connection with thread etc. */
new_connection(callid, call);
async_new_connection(callid, call, client_connection);
break;
default:
ipc_answer_fast(callid, EHANGUP, 0, 0);