391
390
static hash_table_t conn_hash_table;
392
391
static LIST_INITIALIZE(timeout_list);
394
static hash_index_t client_hash(unsigned long key[])
398
return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
401
static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
407
client_t *client = hash_table_get_instance(item, client_t, link);
408
return (key[0] == LOWER32(client->in_task_id) &&
409
(key[1] == UPPER32(client->in_task_id)));
412
static void client_remove(link_t *item)
393
static size_t client_key_hash(void *k)
395
task_id_t key = *(task_id_t*)k;
399
static size_t client_hash(const ht_link_t *item)
401
client_t *client = hash_table_get_inst(item, client_t, link);
402
return client_key_hash(&client->in_task_id);
405
static bool client_key_equal(void *k, const ht_link_t *item)
407
task_id_t key = *(task_id_t*)k;
408
client_t *client = hash_table_get_inst(item, client_t, link);
409
return key == client->in_task_id;
416
413
/** Operations for the client hash table. */
417
static hash_table_operations_t client_hash_table_ops = {
414
static hash_table_ops_t client_hash_table_ops = {
418
415
.hash = client_hash,
419
.compare = client_compare,
420
.remove_callback = client_remove
416
.key_hash = client_key_hash,
417
.key_equal = client_key_equal,
419
.remove_callback = NULL
423
422
/** Compute hash into the connection hash table based on the source phone hash.
427
426
* @return Index into the connection hash table.
430
static hash_index_t conn_hash(unsigned long key[])
434
return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
437
/** Compare hash table item with a key.
439
* @param key Array containing the source phone hash as the only item.
440
* @param keys Expected 1 but ignored.
441
* @param item Connection hash table item.
443
* @return True on match, false otherwise.
446
static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
451
connection_t *conn = hash_table_get_instance(item, connection_t, link);
452
return (key[0] == conn->in_phone_hash);
455
static void conn_remove(link_t *item)
429
static size_t conn_key_hash(void *key)
431
sysarg_t in_phone_hash = *(sysarg_t*)key;
432
return in_phone_hash ;
435
static size_t conn_hash(const ht_link_t *item)
437
connection_t *conn = hash_table_get_inst(item, connection_t, link);
438
return conn_key_hash(&conn->in_phone_hash);
441
static bool conn_key_equal(void *key, const ht_link_t *item)
443
sysarg_t in_phone_hash = *(sysarg_t*)key;
444
connection_t *conn = hash_table_get_inst(item, connection_t, link);
445
return (in_phone_hash == conn->in_phone_hash);
459
449
/** Operations for the connection hash table. */
460
static hash_table_operations_t conn_hash_table_ops = {
450
static hash_table_ops_t conn_hash_table_ops = {
461
451
.hash = conn_hash,
462
.compare = conn_compare,
463
.remove_callback = conn_remove
452
.key_hash = conn_key_hash,
453
.key_equal = conn_key_equal,
455
.remove_callback = NULL
466
458
/** Sort in current fibril's timeout request.
509
501
futex_down(&async_futex);
511
unsigned long key = call->in_phone_hash;
512
link_t *hlp = hash_table_find(&conn_hash_table, &key);
503
ht_link_t *hlp = hash_table_find(&conn_hash_table, &call->in_phone_hash);
515
506
futex_up(&async_futex);
519
connection_t *conn = hash_table_get_instance(hlp, connection_t, link);
510
connection_t *conn = hash_table_get_inst(hlp, connection_t, link);
521
512
msg_t *msg = malloc(sizeof(*msg));
636
627
futex_down(&async_futex);
639
gettimeofday(&conn->wdata.to_event.expires, NULL);
630
getuptime(&conn->wdata.to_event.expires);
640
631
tv_add(&conn->wdata.to_event.expires, usecs);
642
633
conn->wdata.to_event.inlist = false;
697
688
static client_t *async_client_get(task_id_t client_id, bool create)
699
unsigned long key[2] = {
703
690
client_t *client = NULL;
705
692
futex_down(&async_futex);
706
link_t *lnk = hash_table_find(&client_hash_table, key);
693
ht_link_t *lnk = hash_table_find(&client_hash_table, &client_id);
708
client = hash_table_get_instance(lnk, client_t, link);
695
client = hash_table_get_inst(lnk, client_t, link);
709
696
atomic_inc(&client->refcnt);
710
697
} else if (create) {
711
698
client = malloc(sizeof(client_t));
714
701
client->data = async_client_data_create();
716
703
atomic_set(&client->refcnt, 1);
717
hash_table_insert(&client_hash_table, key, &client->link);
704
hash_table_insert(&client_hash_table, &client->link);
725
712
static void async_client_put(client_t *client)
728
unsigned long key[2] = {
729
LOWER32(client->in_task_id),
730
UPPER32(client->in_task_id)
733
716
futex_down(&async_futex);
735
718
if (atomic_predec(&client->refcnt) == 0) {
736
hash_table_remove(&client_hash_table, key, 2);
719
hash_table_remove(&client_hash_table, &client->in_task_id);
829
812
* Remove myself from the connection hash table.
831
814
futex_down(&async_futex);
832
unsigned long key = fibril_connection->in_phone_hash;
833
hash_table_remove(&conn_hash_table, &key, 1);
815
hash_table_remove(&conn_hash_table, &fibril_connection->in_phone_hash);
834
816
futex_up(&async_futex);
916
898
/* Add connection to the connection hash table */
917
unsigned long key = conn->in_phone_hash;
919
900
futex_down(&async_futex);
920
hash_table_insert(&conn_hash_table, &key, &conn->link);
901
hash_table_insert(&conn_hash_table, &conn->link);
921
902
futex_up(&async_futex);
923
904
fibril_add_ready(conn->wdata.fid);
1110
1091
void __async_init(void)
1112
if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
1113
2, &client_hash_table_ops))
1093
if (!hash_table_create(&client_hash_table, 0, 0, &client_hash_table_ops))
1116
if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS,
1117
1, &conn_hash_table_ops))
1096
if (!hash_table_create(&conn_hash_table, 0, 0, &conn_hash_table_ops))
1120
1099
session_ns = (async_sess_t *) malloc(sizeof(async_sess_t));
1412
1391
msg->wdata.fid = fibril_get_id();
1414
gettimeofday(&msg->wdata.to_event.expires, NULL);
1393
getuptime(&msg->wdata.to_event.expires);
1415
1394
tv_add(&msg->wdata.to_event.expires, timeout);
1417
1396
futex_down(&async_futex);
2166
2145
int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
2168
return ipc_share_in_finalize(callid, src, flags);
2147
return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags,
2148
(sysarg_t) __entry);
2171
2151
/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
2233
2213
int async_share_out_finalize(ipc_callid_t callid, void **dst)
2235
return ipc_share_out_finalize(callid, dst);
2215
return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
2238
2218
/** Start IPC_M_DATA_READ using the async framework.
2317
2297
int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
2319
return ipc_data_read_finalize(callid, src, size);
2299
return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
2322
2302
/** Wrapper for forwarding any read request
2420
2400
int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
2422
return ipc_data_write_finalize(callid, dst, size);
2402
return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
2425
2405
/** Wrapper for receiving binary data or strings