cb22561995-10-11Fredrik Hübinette (Hubbe) /*\ ||| This file a part of uLPC, and is copyright by Fredrik Hubinette ||| uLPC is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "macros.h" #include "callback.h"
8f4f881996-06-20Fredrik Hübinette (Hubbe) struct callback
5267b71995-08-09Fredrik Hübinette (Hubbe) {
8f4f881996-06-20Fredrik Hübinette (Hubbe)  struct callback *next; callback_func call; callback_func free_func; void *arg;
5267b71995-08-09Fredrik Hübinette (Hubbe) }; struct callback *first_callback =0;
8f4f881996-06-20Fredrik Hübinette (Hubbe) struct callback *free_callbacks =0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
8f4f881996-06-20Fredrik Hübinette (Hubbe) #define CALLBACK_CHUNK 128
5267b71995-08-09Fredrik Hübinette (Hubbe) 
8f4f881996-06-20Fredrik Hübinette (Hubbe) struct callback_block { struct callback_block *next; struct callback callbacks[CALLBACK_CHUNK]; };
5267b71995-08-09Fredrik Hübinette (Hubbe) 
8f4f881996-06-20Fredrik Hübinette (Hubbe) static struct callback *get_free_callback()
5267b71995-08-09Fredrik Hübinette (Hubbe) {
8f4f881996-06-20Fredrik Hübinette (Hubbe)  struct callback *tmp; if(!(tmp=free_callbacks)) { int e; struct callback_block *tmp2;
3592891996-06-21Fredrik Hübinette (Hubbe)  tmp2=ALLOC_STRUCT(callback_block);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ddea551996-07-01Fredrik Hübinette (Hubbe)  for(e=0;e<(int)sizeof(CALLBACK_CHUNK);e++)
8f4f881996-06-20Fredrik Hübinette (Hubbe)  {
3592891996-06-21Fredrik Hübinette (Hubbe)  tmp2->callbacks[e].next=tmp; tmp=tmp2->callbacks+e;
8f4f881996-06-20Fredrik Hübinette (Hubbe)  } } free_callbacks=tmp->next; return tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
ddea551996-07-01Fredrik Hübinette (Hubbe) void call_callback(struct callback **ptr, void *arg)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
8f4f881996-06-20Fredrik Hübinette (Hubbe)  struct callback *l;
5267b71995-08-09Fredrik Hübinette (Hubbe)  while(l=*ptr) {
ddea551996-07-01Fredrik Hübinette (Hubbe)  if(l->call) l->call(l,l->arg, arg);
8f4f881996-06-20Fredrik Hübinette (Hubbe)  if(!l->call)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { *ptr=l->next;
8f4f881996-06-20Fredrik Hübinette (Hubbe)  l->next=free_callbacks; free_callbacks=l;
ddea551996-07-01Fredrik Hübinette (Hubbe)  }else{ ptr=& l->next;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } }
8f4f881996-06-20Fredrik Hübinette (Hubbe) struct callback *add_to_callback(struct callback **ptr,
3592891996-06-21Fredrik Hübinette (Hubbe)  callback_func call, void *arg, callback_func free_func)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
8f4f881996-06-20Fredrik Hübinette (Hubbe)  struct callback *l; l=get_free_callback(); l->call=call; l->arg=arg;
5267b71995-08-09Fredrik Hübinette (Hubbe)  l->next=*ptr; *ptr=l;
8f4f881996-06-20Fredrik Hübinette (Hubbe)  return l;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
8f4f881996-06-20Fredrik Hübinette (Hubbe) /* It is not actually freed until next time this callback is called */ void *remove_callback(struct callback *l)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
8f4f881996-06-20Fredrik Hübinette (Hubbe)  l->call=0; return l->arg;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
8f4f881996-06-20Fredrik Hübinette (Hubbe) void free_callback(struct callback **ptr)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
8f4f881996-06-20Fredrik Hübinette (Hubbe)  struct callback *l;
5267b71995-08-09Fredrik Hübinette (Hubbe)  while(l=*ptr) {
3592891996-06-21Fredrik Hübinette (Hubbe)  if(l->arg && l->free_func)
ddea551996-07-01Fredrik Hübinette (Hubbe)  l->free_func(l, l->arg, 0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  *ptr=l->next;
8f4f881996-06-20Fredrik Hübinette (Hubbe)  l->next=free_callbacks; free_callbacks=l;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }