Changeset 8dab988 in mainline
- Timestamp:
- 2018-06-27T18:44:07Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 62c4297
- Parents:
- 45c39ad
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/server.c
r45c39ad r8dab988 122 122 #include "../private/fibril.h" 123 123 124 #define DPRINTF(...) ((void) 0) 125 124 126 /** Async framework global futex */ 125 127 futex_t async_futex = FUTEX_INITIALIZER; … … 180 182 } connection_t; 181 183 184 /* Member of notification_t::msg_list. */ 185 typedef struct { 186 link_t link; 187 ipc_call_t calldata; 188 } notification_msg_t; 189 182 190 /* Notification data */ 183 191 typedef struct { … … 197 205 void *arg; 198 206 199 /** Data of the most recent notification. */ 200 ipc_call_t calldata; 201 202 /** 203 * How many notifications with this `imethod` arrived since it was last 204 * handled. If `count` > 1, `calldata` only holds the data for the most 205 * recent such notification, all the older data being lost. 206 * 207 * `async_spawn_notification_handler()` can be used to increase the 208 * number of notifications that can be processed simultaneously, 209 * reducing the likelihood of losing them when the handler blocks. 210 */ 211 long count; 207 /** List of arrived notifications. */ 208 list_t msg_list; 212 209 } notification_t; 213 210 … … 249 246 static LIST_INITIALIZE(notification_queue); 250 247 static FIBRIL_SEMAPHORE_INITIALIZE(notification_semaphore, 0); 248 249 static LIST_INITIALIZE(notification_freelist); 250 static long notification_freelist_total = 0; 251 static long notification_freelist_used = 0; 251 252 252 253 static sysarg_t notification_avail = 0; … … 709 710 notification_t *notification = list_get_instance( 710 711 list_first(¬ification_queue), notification_t, qlink); 711 list_remove(¬ification->qlink);712 712 713 713 async_notification_handler_t handler = notification->handler; 714 714 void *arg = notification->arg; 715 ipc_call_t calldata = notification->calldata; 716 long count = notification->count; 717 718 notification->count = 0; 715 716 notification_msg_t *m = list_pop(¬ification->msg_list, 717 notification_msg_t, link); 718 assert(m); 719 ipc_call_t calldata = m->calldata; 720 721 notification_freelist_used--; 722 723 if (notification_freelist_total > 64 && 724 notification_freelist_total > 2 * notification_freelist_used) { 725 /* Going to free the structure if we have too much. */ 726 notification_freelist_total--; 727 } else { 728 /* Otherwise add to freelist. */ 729 list_append(&m->link, ¬ification_freelist); 730 m = NULL; 731 } 732 733 if (list_empty(¬ification->msg_list)) 734 list_remove(¬ification->qlink); 719 735 720 736 futex_unlock(¬ification_futex); 721 722 // FIXME: Pass count to the handler. It might be important.723 (void) count;724 737 725 738 if (handler) 726 739 handler(&calldata, arg); 740 741 free(m); 727 742 } 728 743 … … 760 775 futex_lock(¬ification_futex); 761 776 777 notification_msg_t *m = list_pop(¬ification_freelist, 778 notification_msg_t, link); 779 780 if (!m) { 781 futex_unlock(¬ification_futex); 782 m = malloc(sizeof(notification_msg_t)); 783 if (!m) { 784 DPRINTF("Out of memory.\n"); 785 abort(); 786 } 787 788 futex_lock(¬ification_futex); 789 notification_freelist_total++; 790 } 791 762 792 ht_link_t *link = hash_table_find(¬ification_hash_table, 763 793 &IPC_GET_IMETHOD(*call)); … … 765 795 /* Invalid notification. */ 766 796 // TODO: Make sure this can't happen and turn it into assert. 797 notification_freelist_total--; 767 798 futex_unlock(¬ification_futex); 799 free(m); 768 800 return; 769 801 } … … 772 804 hash_table_get_inst(link, notification_t, htlink); 773 805 774 notification->count++; 775 notification->calldata = *call; 776 777 if (link_in_use(¬ification->qlink)) { 778 /* Notification already queued. */ 779 futex_unlock(¬ification_futex); 780 return; 781 } 782 783 list_append(¬ification->qlink, ¬ification_queue); 806 notification_freelist_used++; 807 m->calldata = *call; 808 list_append(&m->link, ¬ification->msg_list); 809 810 if (!link_in_use(¬ification->qlink)) 811 list_append(¬ification->qlink, ¬ification_queue); 812 784 813 futex_unlock(¬ification_futex); 785 814 … … 802 831 notification->handler = handler; 803 832 notification->arg = arg; 833 834 list_initialize(¬ification->msg_list); 804 835 805 836 fid_t fib = 0;
Note:
See TracChangeset
for help on using the changeset viewer.