#include "signal.h" #include "board.h" #include "stdlib.h" #include "stdio.h" #include "debug.h" typedef struct{ void *mutex; signal_list *head; }self_def; static self_def g_self; int signal_init(void) { self_def *s=&g_self; if(s->mutex==0) { s->mutex=rt_mutex_create("signal_",RT_IPC_FLAG_FIFO); } return 0; } static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte) { for(int i=0;irun) { rt_mq_recv(s->mb,msg,msg_size,RT_WAITING_FOREVER); SLOT_FUN_RUN(msg->fun,msg->param); } free(msg); } // 创建一个线程 sig_thread thread_creat(int pro) { static uint16_t count=0; char name[20]={0}; slot_run_def *run=calloc(1,sizeof(slot_run_def)); run->run=1; sprintf(name,"sig_mq#%d",count); run->mb=rt_mq_create(name,(sizeof(slot_msg_def)+sizeof(uint32_t)*8),50,RT_IPC_FLAG_FIFO); sprintf(name,"sig_t#%d",count); rt_thread_t rt_t=rt_thread_create(name,slot_run,run,2048,pro,20); rt_thread_startup(rt_t); count++; return run->mb; } void thread_delete(sig_thread t) { // 删除线程需要删除与此线程相关的所有信号槽 // 删除消息队列 param_check(0); } // 如果这个类的信号已注册 static signal_list *find(void *sig_obj,void *signal_) { self_def *s=&g_self; signal_list *l=s->head; while(l!=0) { if(l->signal_==signal_&&l->sig_obj==sig_obj) return l; l=l->next; } return 0; } int connect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot) { self_def *s=&g_self; signal_def *sig; sig=signal_find(signal_); if(sig==0) return -1; rt_mutex_take(s->mutex,RT_WAITING_FOREVER); slot_list *slo=calloc(1,sizeof(slot_list)); param_check(slo); slo->fun=slot; slo->mb=t; slo->next=0; slo->obj=slot_obj; signal_list *sig_l=find(sig_obj,signal_); if(sig_l==0){ sig_l=calloc(1,sizeof(signal_list)); param_check(sig_l); sig_l->signal_=signal_; sig_l->sig_obj=sig_obj; sig_l->next=s->head; s->head=sig_l; } slo->next=sig_l->head; sig_l->head=slo; //DBG_LOG("signal connect:%08x",slo); rt_mutex_release(s->mutex); return 0; } int disconnect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot) { self_def *s=&g_self; signal_list *sig; sig=find(sig_obj,signal_); if(sig==0) return -1; int ret=-1; rt_mutex_take(s->mutex,RT_WAITING_FOREVER); slot_list *next=sig->head; slot_list *prev=0; while(next!=0) { if(next->fun==slot&&next->obj==slot_obj) { if(prev) prev->next=next->next; else sig->head=next->next; //DBG_LOG("signal disconnect:%08x",next); free(next); ret=0; break; } prev=next; next=next->next; } rt_mutex_release(s->mutex); return ret; } // 消除与指定对象相关的所有信号槽连接 int disconnect_sig(void *sig_obj) { self_def *s=&g_self; rt_mutex_take(s->mutex,RT_WAITING_FOREVER); signal_list *sig=s->head; signal_list *prev_sig=0; while(sig!=0) { if(sig->sig_obj==sig_obj) { slot_list *next=sig->head; while(next!=0) { sig->head=next->next; free(next); next=sig->head; } if(prev_sig) prev_sig=sig->next; else s->head=sig->next; free(sig); break; } prev_sig=sig; sig=sig->next; } rt_mutex_release(s->mutex); return 0; } // 消除与指定对象相关的所有信号槽连接 int disconnect_slot(void *slot_obj) { self_def *s=&g_self; rt_mutex_take(s->mutex,RT_WAITING_FOREVER); signal_list *sig=s->head; while(sig!=0) { slot_list *next=sig->head; slot_list *prev=0; while(next!=0) { if(next->obj==slot_obj) { if(prev) prev->next=next->next; else sig->head=next->next; free(next); break; } prev=next; next=next->next; } sig=sig->next; } rt_mutex_release(s->mutex); return 0; } signal_def *signal_find(void *signal_) { extern const int signalstruct$$Base; extern const int signalstruct$$Limit; signal_def *start=(signal_def *)&signalstruct$$Base; signal_def *end=(signal_def *)&signalstruct$$Limit; for(signal_def *t=start;tsignal_==signal_) { return t; } } return 0; } // 发送信号 int _signal_emit(void *sig_obj,void *signal_,uint32_t *param,int param_num) { self_def *s=&g_self; signal_list *sig=find(sig_obj,signal_); if(sig==0) return -1; if(param_num>7) return -2; int size=sizeof(slot_msg_def)+sizeof(uint32_t)*(8); slot_msg_def *m=malloc(size); rt_mutex_take(s->mutex,RT_WAITING_FOREVER); slot_list *h=sig->head; m->param_num=param_num; m->src=signal_; while(h) { m->fun=h->fun; if(h->obj) { cpy4byte(m->param+1,param,param_num); m->param[0]=(uint32_t)h->obj; }else{ cpy4byte(m->param,param,param_num); } if(h->mb){ rt_mq_send(h->mb,m,size); }else{ SLOT_FUN_RUN(m->fun,m->param); } h=h->next; } rt_mutex_release(s->mutex); free(m); return 0; }