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 | } |