| Index: emcore/trunk/button.c |
| — | — | @@ -26,71 +26,84 @@ |
| 27 | 27 | #include "thread.h"
|
| 28 | 28 |
|
| 29 | 29 |
|
| 30 | | -#ifndef BUTTON_MAX_HOOKS
|
| 31 | | -#define BUTTON_MAX_HOOKS 16
|
| 32 | | -#endif
|
| 33 | | -
|
| 34 | | -
|
| 35 | | -static struct button_hook_entry button_hooks[BUTTON_MAX_HOOKS] IBSS_ATTR;
|
| | 30 | +static struct button_hook_entry* head_button_hook IBSS_ATTR;
|
| 36 | 31 | static struct mutex button_mutex;
|
| 37 | 32 |
|
| 38 | 33 |
|
| 39 | 34 | void button_init()
|
| 40 | 35 | {
|
| 41 | | - memset(button_hooks, 0, sizeof(button_hooks));
|
| | 36 | + head_button_hook = NULL;
|
| 42 | 37 | mutex_init(&button_mutex);
|
| 43 | 38 | }
|
| 44 | 39 |
|
| 45 | 40 | int button_register_handler(void (*handler)(enum button_event, int which, int value))
|
| 46 | 41 | {
|
| 47 | | - int i;
|
| | 42 | + struct button_hook_entry* hook;
|
| | 43 | + hook = (struct button_hook_entry*)malloc(sizeof(struct button_hook_entry));
|
| | 44 | + hook->owner = current_thread;
|
| | 45 | + hook->handler = handler;
|
| 48 | 46 | mutex_lock(&button_mutex, TIMEOUT_BLOCK);
|
| 49 | | - for (i = 0; i < BUTTON_MAX_HOOKS; i++)
|
| 50 | | - if (button_hooks[i].owner == NULL)
|
| 51 | | - {
|
| 52 | | - button_hooks[i].owner = current_thread;
|
| 53 | | - button_hooks[i].handler = handler;
|
| 54 | | - mutex_unlock(&button_mutex);
|
| 55 | | - return 0;
|
| 56 | | - }
|
| | 47 | + hook->next = head_button_hook;
|
| | 48 | + head_button_hook = hook;
|
| 57 | 49 | mutex_unlock(&button_mutex);
|
| 58 | | - return -1;
|
| | 50 | + return 0;
|
| 59 | 51 | }
|
| 60 | 52 |
|
| 61 | 53 | int button_unregister_handler(void (*handler)(enum button_event, int which, int value))
|
| 62 | 54 | {
|
| 63 | | - int i;
|
| | 55 | + struct button_hook_entry* h;
|
| | 56 | + struct button_hook_entry* handle = NULL;
|
| | 57 | + int result = 0;
|
| 64 | 58 | mutex_lock(&button_mutex, TIMEOUT_BLOCK);
|
| 65 | | - for (i = 0; i < BUTTON_MAX_HOOKS; i++)
|
| 66 | | - if (button_hooks[i].handler == handler)
|
| | 59 | + if (head_button_hook && head_button_hook->handler == handler)
|
| | 60 | + {
|
| | 61 | + handle = head_button_hook;
|
| | 62 | + head_button_hook = head_button_hook->next;
|
| | 63 | + }
|
| | 64 | + else
|
| | 65 | + {
|
| | 66 | + for (h = head_button_hook; h && h->next->handler != handler; h = h->next);
|
| | 67 | + if (h)
|
| 67 | 68 | {
|
| 68 | | - button_hooks[i].owner = NULL;
|
| 69 | | - button_hooks[i].handler = NULL;
|
| 70 | | - mutex_unlock(&button_mutex);
|
| 71 | | - return 0;
|
| | 69 | + handle = h->next;
|
| | 70 | + h->next = h->next->next;
|
| 72 | 71 | }
|
| | 72 | + else result = -1;
|
| | 73 | + }
|
| 73 | 74 | mutex_unlock(&button_mutex);
|
| 74 | | - return -1;
|
| | 75 | + if (handle) free(handle);
|
| | 76 | + return result;
|
| 75 | 77 | }
|
| 76 | 78 |
|
| 77 | 79 | void button_send_event(enum button_event eventtype, int which, int value)
|
| 78 | 80 | {
|
| 79 | 81 | DEBUGF("Sending button event: %d, %02X, %02X", eventtype, which, value);
|
| 80 | | - int i;
|
| 81 | | - for (i = 0; i < BUTTON_MAX_HOOKS; i++)
|
| 82 | | - if (button_hooks[i].owner != NULL)
|
| 83 | | - button_hooks[i].handler(eventtype, which, value);
|
| | 82 | + struct button_hook_entry* h;
|
| | 83 | + mutex_lock(&button_mutex, TIMEOUT_BLOCK);
|
| | 84 | + for (h = head_button_hook; h; h = h->next)
|
| | 85 | + h->handler(eventtype, which, value);
|
| | 86 | + mutex_unlock(&button_mutex);
|
| 84 | 87 | }
|
| 85 | 88 |
|
| 86 | 89 | void button_unregister_all_of_thread(struct scheduler_thread* process)
|
| 87 | 90 | {
|
| 88 | | - int i;
|
| | 91 | + struct button_hook_entry* h;
|
| | 92 | + struct button_hook_entry* prev;
|
| 89 | 93 | mutex_lock(&button_mutex, TIMEOUT_BLOCK);
|
| 90 | | - for (i = 0; i < BUTTON_MAX_HOOKS; i++)
|
| 91 | | - if (button_hooks[i].owner == process)
|
| | 94 | + while (head_button_hook && head_button_hook->owner == process)
|
| | 95 | + {
|
| | 96 | + prev = head_button_hook;
|
| | 97 | + head_button_hook = head_button_hook->next;
|
| | 98 | + free(prev);
|
| | 99 | + }
|
| | 100 | + for (h = head_button_hook->next; h; h = h->next)
|
| | 101 | + {
|
| | 102 | + while (h && h->owner == process)
|
| 92 | 103 | {
|
| 93 | | - button_hooks[i].owner = NULL;
|
| 94 | | - button_hooks[i].handler = NULL;
|
| | 104 | + prev->next = h->next;
|
| | 105 | + free(h);
|
| 95 | 106 | }
|
| | 107 | + prev = h;
|
| | 108 | + }
|
| 96 | 109 | mutex_unlock(&button_mutex);
|
| 97 | 110 | }
|
| Index: emcore/trunk/button.h |
| — | — | @@ -43,6 +43,7 @@ |
| 44 | 44 |
|
| 45 | 45 | struct button_hook_entry
|
| 46 | 46 | {
|
| | 47 | + struct button_hook_entry* next;
|
| 47 | 48 | struct scheduler_thread* owner;
|
| 48 | 49 | void (*handler)(enum button_event, int which, int value);
|
| 49 | 50 | };
|