bluedroid thread

bluedroid的消息传递机制

1 创建一个队列:
btu_bta_msg_queue = fixed_queue_new(SIZE_MAX);
	fixed_queue_t *ret = osi_calloc(sizeof(fixed_queue_t));
	//队列里面最大的容量
	ret->capacity = capacity;
	//链表
	ret->list = list_new(NULL);
	//创建二个eventfd类型的fd,可以用epoll来监控
	//enqueue_sem访问链表时,要先获取这个值减1
	ret->enqueue_sem = semaphore_new(capacity);
		ret->fd = eventfd(value, EFD_SEMAPHORE); //EFD_SEMAPHORE实现每次读减1的效果
	//dequeue_sem当添加一个消息到链表时,加1
	ret->dequeue_sem = semaphore_new(0);


2 创建一个线程:
bt_workqueue_thread = thread_new(BT_WORKQUEUE_NAME);
	ret->reactor = reactor_new();
		ret->epoll_fd = epoll_create(MAX_EVENTS); //创建一个epoll
	
	//创建一个内部队列,创建过程跟上面一样
	ret->work_queue = fixed_queue_new(work_queue_capacity);

	pthread_create(&ret->pthread, NULL, run_thread, &start);
		run_thread
			//获取内部队列的dequeue_sem
			int fd = fixed_queue_get_dequeue_fd(thread->work_queue);
			//向epoll添加一个读监控
			reactor_object_t *object = (reactor_object_t *)osi_calloc(sizeof(reactor_object_t));
			object->fd = fd;
			object->read_ready = read_ready; //work_queue_read_cb
			struct epoll_event event;
			event.events |= (EPOLLIN | EPOLLRDHUP);
			epoll_ctl(reactor->epoll_fd, EPOLL_CTL_ADD, fd, &event)
			reactor_start
			while (1)
				epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1)
				//当有事件
				if (events[j].events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR) && object->read_ready)
					object->read_ready(object->context);
					work_queue_read_cb
						//void *context = thread->work_queue; 内部队列
						fixed_queue_t *queue = (fixed_queue_t *)context;
						//取出消息,然后删掉该条消息
						work_item_t *item = fixed_queue_dequeue(queue); 
						//执行最终的函数
						item->func(item->context);

3 上面有个问题谁去填充线程内部队列,答案就是:		
thread_post(bt_workqueue_thread, btu_task_start_up, NULL);
	work_item_t *item = (work_item_t *)osi_malloc(sizeof(work_item_t));
	item->func = func;
	item->context = context;
	fixed_queue_enqueue(thread->work_queue, item);

4 这里有个问题,第一步创建的队列我们没有使用,这里介绍另外一个函数,看下它的实现:
fixed_queue_register_dequeue(
		btu_bta_msg_queue, 							//第一步创建的队列
		thread_get_reactor(bt_workqueue_thread),  	//线程的epoll相关的结构体
		btu_bta_msg_ready,							//最终要执行的函数
		NULL);
	queue->dequeue_ready = ready_cb;
	queue->dequeue_context = context;
	queue->dequeue_object = reactor_register(
						reactor,
						fixed_queue_get_dequeue_fd(queue), //新队列的dequeue_sem的fd
						queue,
						internal_dequeue_ready,
						NULL
						);
			//向epoll添加一个读监控(新队列的dequeue_sem的fd)
			reactor_object_t *object = (reactor_object_t *)osi_calloc(sizeof(reactor_object_t));
			object->fd = fd;
			object->read_ready = read_ready; //btu_bta_msg_ready
			struct epoll_event event;
			event.events |= (EPOLLIN | EPOLLRDHUP);
			epoll_ctl(reactor->epoll_fd, EPOLL_CTL_ADD, fd, &event)
				//当有事件
				if (events[j].events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR) && object->read_ready)
					object->read_ready(object->context);
					btu_bta_msg_ready
						//取出消息,然后删掉该条消息
						BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
						//自定义处理消息函数
						bta_sys_event(p_msg);
						
5 最后一个问题:如何给这个队列传递消息:进队列如下:
fixed_queue_enqueue(btu_bta_msg_queue, p_msg);

总结:
核心就是通过线程的epoll监控每个队列里面的event_fd(通过fixed_queue_register_dequeue注册新队列以及新处理函数)
有两种方式传递处理消息:
第一使用线程内部自带的队列:thread_post(bt_workqueue_thread, btu_task_start_up, NULL);
第二自己创建一个队列:fixed_queue_new / 注册fixed_queue_register_dequeue(自定义处理函数)/ 进队列fixed_queue_enqueue,自由度更大

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值