Subversion Repositories HelenOS-historic

Rev

Rev 1405 | Rev 1408 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1405 Rev 1407
Line 58... Line 58...
58
 *  }
58
 *  }
59
 *
59
 *
60
 *
60
 *
61
 * 2) Multithreaded server application
61
 * 2) Multithreaded server application
62
 * main() {
62
 * main() {
63
 *      wait_for_connection(new_connection);
63
 *      async_manager();
64
 * }
64
 * }
65
 *
65
 *
66
 *
66
 *
67
 * new_connection(int connection) {
67
 * client_connection(icallid, *icall) {
68
 *       accept(connection);
68
 *       if (want_refuse) {
-
 
69
 *           ipc_answer_fast(icallid, ELIMIT, 0, 0);
69
 *       msg = get_msg();
70
 *           return;
70
 *       handle(msg);
71
 *       }
71
 *       answer(msg);
72
 *       ipc_answer_fast(icallid, 0, 0, 0);
72
 *
73
 *
-
 
74
 *       callid = async_get_call(&call);
-
 
75
 *       handle(callid, call);
-
 
76
 *       ipc_answer_fast(callid, 1,2,3);
-
 
77
 *
73
 *       msg = get_msg();
78
 *       callid = async_get_call(&call);
74
 *       ....
79
 *       ....
75
 * }
80
 * }
76
 *
81
 *
77
 * TODO: Detaching/joining dead psthreads?
82
 * TODO: Detaching/joining dead psthreads?
78
 */
83
 */
Line 102... Line 107...
102
    pstid_t ptid;                /**< Thread associated with this connection */
107
    pstid_t ptid;                /**< Thread associated with this connection */
103
    int active;                     /**< If this thread is currently active */
108
    int active;                     /**< If this thread is currently active */
104
    /* Structures for connection opening packet */
109
    /* Structures for connection opening packet */
105
    ipc_callid_t callid;
110
    ipc_callid_t callid;
106
    ipc_call_t call;
111
    ipc_call_t call;
-
 
112
    void (*cthread)(ipc_callid_t,ipc_call_t *);
107
} connection_t;
113
} connection_t;
108
 
114
 
109
__thread connection_t *PS_connection;
115
__thread connection_t *PS_connection;
110
 
116
 
111
/* Hash table functions */
117
/* Hash table functions */
Line 223... Line 229...
223
    unsigned long key;
229
    unsigned long key;
224
    msg_t *msg;
230
    msg_t *msg;
225
 
231
 
226
    /* Setup thread local connection pointer */
232
    /* Setup thread local connection pointer */
227
    PS_connection = (connection_t *)arg;
233
    PS_connection = (connection_t *)arg;
228
    client_connection(PS_connection->callid, &PS_connection->call);
234
    PS_connection->cthread(PS_connection->callid, &PS_connection->call);
229
 
235
 
230
    /* Remove myself from connection hash table */
236
    /* Remove myself from connection hash table */
231
    futex_down(&conn_futex);
237
    futex_down(&conn_futex);
232
    key = PS_connection->in_phone_hash;
238
    key = PS_connection->in_phone_hash;
233
    hash_table_remove(&conn_hash_table, &key, 1);
239
    hash_table_remove(&conn_hash_table, &key, 1);
Line 245... Line 251...
245
 *
251
 *
246
 * Creates new thread for connection, fills in connection
252
 * Creates new thread for connection, fills in connection
247
 * structures and inserts it into the hash table, so that
253
 * structures and inserts it into the hash table, so that
248
 * later we can easily do routing of messages to particular
254
 * later we can easily do routing of messages to particular
249
 * threads.
255
 * threads.
-
 
256
 *
-
 
257
 * @param callid Callid of the IPC_M_CONNECT_ME_TO packet
-
 
258
 * @param call Call data of the opening packet
-
 
259
 * @param cthread Thread function that should be called upon
-
 
260
 *                opening the connection
-
 
261
 * @return New thread id
250
 */
262
 */
251
static void new_connection(ipc_callid_t callid, ipc_call_t *call)
263
pstid_t async_new_connection(ipc_callid_t callid, ipc_call_t *call,
-
 
264
                 void (*cthread)(ipc_callid_t,ipc_call_t *))
252
{
265
{
253
    pstid_t ptid;
266
    pstid_t ptid;
254
    connection_t *conn;
267
    connection_t *conn;
255
    unsigned long key;
268
    unsigned long key;
256
 
269
 
257
    conn = malloc(sizeof(*conn));
270
    conn = malloc(sizeof(*conn));
258
    if (!conn) {
271
    if (!conn) {
259
        ipc_answer_fast(callid, ENOMEM, 0, 0);
272
        ipc_answer_fast(callid, ENOMEM, 0, 0);
260
        return;
273
        return NULL;
261
    }
274
    }
262
    conn->in_phone_hash = IPC_GET_ARG3(*call);
275
    conn->in_phone_hash = IPC_GET_ARG3(*call);
263
    list_initialize(&conn->msg_queue);
276
    list_initialize(&conn->msg_queue);
264
    conn->ptid = psthread_create(connection_thread, conn);
277
    conn->ptid = psthread_create(connection_thread, conn);
265
    conn->callid = callid;
278
    conn->callid = callid;
266
    conn->call = *call;
279
    conn->call = *call;
267
    conn->active = 1; /* We will activate it asap */
280
    conn->active = 1; /* We will activate it asap */
-
 
281
    conn->cthread = cthread;
268
    list_initialize(&conn->link);
282
    list_initialize(&conn->link);
269
    if (!conn->ptid) {
283
    if (!conn->ptid) {
270
        free(conn);
284
        free(conn);
271
        ipc_answer_fast(callid, ENOMEM, 0, 0);
285
        ipc_answer_fast(callid, ENOMEM, 0, 0);
272
        return;
286
        return NULL;
273
    }
287
    }
274
    key = conn->in_phone_hash;
288
    key = conn->in_phone_hash;
275
    futex_down(&conn_futex);
289
    futex_down(&conn_futex);
276
    /* Add connection to hash table */
290
    /* Add connection to hash table */
277
    hash_table_insert(&conn_hash_table, &key, &conn->link);
291
    hash_table_insert(&conn_hash_table, &key, &conn->link);
278
    futex_up(&conn_futex);
292
    futex_up(&conn_futex);
279
 
293
 
280
    psthread_add_ready(conn->ptid);
294
    psthread_add_ready(conn->ptid);
-
 
295
 
-
 
296
    return conn->ptid;
281
}
297
}
282
 
298
 
283
/** Handle call to a task */
299
/** Handle call to a task */
284
static void handle_call(ipc_callid_t callid, ipc_call_t *call)
300
static void handle_call(ipc_callid_t callid, ipc_call_t *call)
285
{
301
{
Line 289... Line 305...
289
    switch (IPC_GET_METHOD(*call)) {
305
    switch (IPC_GET_METHOD(*call)) {
290
    case IPC_M_INTERRUPT:
306
    case IPC_M_INTERRUPT:
291
        break;
307
        break;
292
    case IPC_M_CONNECT_ME_TO:
308
    case IPC_M_CONNECT_ME_TO:
293
        /* Open new connection with thread etc. */
309
        /* Open new connection with thread etc. */
294
        new_connection(callid, call);
310
        async_new_connection(callid, call, client_connection);
295
        break;
311
        break;
296
    default:
312
    default:
297
        ipc_answer_fast(callid, EHANGUP, 0, 0);
313
        ipc_answer_fast(callid, EHANGUP, 0, 0);
298
    }
314
    }
299
}
315
}