Rev 2483 | Rev 2485 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2483 | Rev 2484 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | */ |
33 | */ |
34 | 34 | ||
35 | /** |
35 | /** |
36 | * Asynchronous library |
36 | * Asynchronous library |
37 | * |
37 | * |
38 | * The aim of this library is facilitating writing programs utilizing |
38 | * The aim of this library is facilitating writing programs utilizing the |
39 | * the asynchronous nature of HelenOS IPC, yet using a normal way |
39 | * asynchronous nature of HelenOS IPC, yet using a normal way of programming. |
40 | * of programming. |
- | |
41 | * |
40 | * |
42 | * You should be able to write very simple multithreaded programs, |
41 | * You should be able to write very simple multithreaded programs, the async |
43 | * the async framework will automatically take care of most synchronization |
42 | * framework will automatically take care of most synchronization problems. |
44 | * problems. |
- | |
45 | * |
43 | * |
46 | * Default semantics: |
44 | * Default semantics: |
47 | * - send() - send asynchronously. If the kernel refuses to send more |
45 | * - async_send_*(): send asynchronously. If the kernel refuses to send |
48 | * messages, [ try to get responses from kernel, if nothing |
46 | * more messages, [ try to get responses from kernel, if |
49 | * found, might try synchronous ] |
47 | * nothing found, might try synchronous ] |
50 | * |
48 | * |
51 | * Example of use: |
49 | * Example of use (pseudo C): |
52 | * |
50 | * |
53 | * 1) Multithreaded client application |
51 | * 1) Multithreaded client application |
- | 52 | * |
|
54 | * fibril_create(fibril1); |
53 | * fibril_create(fibril1, ...); |
55 | * fibril_create(fibril2); |
54 | * fibril_create(fibril2, ...); |
56 | * ... |
55 | * ... |
57 | * |
56 | * |
58 | * fibril1() { |
57 | * int fibril1(void *arg) |
- | 58 | * { |
|
59 | * conn = ipc_connect_me_to(); |
59 | * conn = ipc_connect_me_to(); |
60 | * c1 = send(conn); |
60 | * c1 = async_send(conn); |
61 | * c2 = send(conn); |
61 | * c2 = async_send(conn); |
62 | * wait_for(c1); |
62 | * async_wait_for(c1); |
63 | * wait_for(c2); |
63 | * async_wait_for(c2); |
- | 64 | * ... |
|
64 | * } |
65 | * } |
65 | * |
66 | * |
66 | * |
67 | * |
67 | * 2) Multithreaded server application |
68 | * 2) Multithreaded server application |
68 | * main() { |
69 | * main() |
- | 70 | * { |
|
69 | * async_manager(); |
71 | * async_manager(); |
70 | * } |
72 | * } |
71 | * |
73 | * |
72 | * |
74 | * |
73 | * client_connection(icallid, *icall) { |
75 | * client_connection(icallid, *icall) |
- | 76 | * { |
|
74 | * if (want_refuse) { |
77 | * if (want_refuse) { |
75 | * ipc_answer_fast(icallid, ELIMIT, 0, 0); |
78 | * ipc_answer_fast(icallid, ELIMIT, 0, 0); |
76 | * return; |
79 | * return; |
77 | * } |
80 | * } |
78 | * ipc_answer_fast(icallid, 0, 0, 0); |
81 | * ipc_answer_fast(icallid, EOK, 0, 0); |
79 | * |
82 | * |
80 | * callid = async_get_call(&call); |
83 | * callid = async_get_call(&call); |
81 | * handle(callid, call); |
84 | * handle_call(callid, call); |
82 | * ipc_answer_fast(callid, 1, 2, 3); |
85 | * ipc_answer_fast(callid, 1, 2, 3); |
83 | * |
86 | * |
84 | * callid = async_get_call(&call); |
87 | * callid = async_get_call(&call); |
85 | * .... |
88 | * .... |
86 | * } |
89 | * } |
87 | * |
90 | * |
88 | */ |
91 | */ |
- | 92 | ||
89 | #include <futex.h> |
93 | #include <futex.h> |
90 | #include <async.h> |
94 | #include <async.h> |
91 | #include <fibril.h> |
95 | #include <fibril.h> |
92 | #include <stdio.h> |
96 | #include <stdio.h> |
93 | #include <libadt/hash_table.h> |
97 | #include <libadt/hash_table.h> |
Line 565... | Line 569... | ||
565 | /** Function to start async_manager as a standalone thread |
569 | /** Function to start async_manager as a standalone thread |
566 | * |
570 | * |
567 | * When more kernel threads are used, one async manager should |
571 | * When more kernel threads are used, one async manager should |
568 | * exist per thread. The particular implementation may change, |
572 | * exist per thread. The particular implementation may change, |
569 | * currently one async_manager is started automatically per kernel |
573 | * currently one async_manager is started automatically per kernel |
570 | * thread except main thread. |
574 | * thread except the main thread. |
571 | */ |
575 | */ |
572 | static int async_manager_thread(void *arg) |
576 | static int async_manager_fibril(void *arg) |
573 | { |
577 | { |
574 | futex_up(&async_futex); |
578 | futex_up(&async_futex); |
575 | /* async_futex is always locked when entering |
579 | /* async_futex is always locked when entering |
576 | * manager */ |
580 | * manager */ |
577 | async_manager_worker(); |
581 | async_manager_worker(); |
Line 582... | Line 586... | ||
582 | /** Add one manager to manager list */ |
586 | /** Add one manager to manager list */ |
583 | void async_create_manager(void) |
587 | void async_create_manager(void) |
584 | { |
588 | { |
585 | fid_t fid; |
589 | fid_t fid; |
586 | 590 | ||
587 | fid = fibril_create(async_manager_thread, NULL); |
591 | fid = fibril_create(async_manager_fibril, NULL); |
588 | fibril_add_manager(fid); |
592 | fibril_add_manager(fid); |
589 | } |
593 | } |
590 | 594 | ||
591 | /** Remove one manager from manager list */ |
595 | /** Remove one manager from manager list */ |
592 | void async_destroy_manager(void) |
596 | void async_destroy_manager(void) |