doubao_chat/lib/net/libduer-device/platform/source-lpb100/lightduer_events.c

177 lines
4.8 KiB
C

/**
* Copyright (2017) Baidu Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File: lightduer_events.c
* Auth: Chang Li (changli@baidu.com)
* Desc: Light duer events looper.
*/
#include "lightduer_events.h"
#include "lightduer_connagent.h"
#include "lightduer_log.h"
#include "lightduer_lib.h"
#include "lightduer_memory.h"
#include "lightduer_priority_conf.h"
#include "hsf.h"
#include "hfmsgq.h"
#define QUEUE_WAIT_FOREVER (0x7fffffff)
typedef struct _duer_events_struct {
hfthread_hande_t _task;
HFMSGQ_HANDLE _queue;
char *_name;
} duer_events_t;
typedef struct _duer_queue_message_s {
duer_events_func _callback;
int _what;
void *_data;
} duer_eq_message;
static long duer_events_timestamp()
{
return hfsys_get_time();
}
static void duer_events_task(void *context)
{
duer_events_t *events = (duer_events_t *)context;
long runtime = 0;
duer_eq_message message;
do {
if (HF_SUCCESS == hfmsgq_recv(events->_queue, &message, QUEUE_WAIT_FOREVER, 0)) {
if (message._callback) {
runtime = duer_events_timestamp();
DUER_LOGD("[%s] <== event begin = %p", events->_name, message._callback);
message._callback(message._what, message._data);
runtime = duer_events_timestamp() - runtime;
if (runtime > 50) {
DUER_LOGW("[%s] <== event end = %p, timespent = %ld", events->_name, message._callback, runtime);
}
}
} else {
DUER_LOGE("[%s] Queue receive failed!", events->_name);
}
} while (1);
}
duer_events_handler duer_events_create(const char *name, size_t stack_size, size_t queue_length)
{
duer_events_t *events = NULL;
int rs = DUER_ERR_FAILED;
do {
if (name == NULL) {
name = "default";
}
events = (duer_events_t *)DUER_MALLOC(sizeof(duer_events_t));
if (!events) {
DUER_LOGE("[%s] Alloc the events resource failed!", events->_name);
break;
}
DUER_MEMSET(events, 0, sizeof(duer_events_t));
events->_name = (char *)DUER_MALLOC(DUER_STRLEN(name) + 1);
if (events->_name) {
DUER_MEMCPY(events->_name, name, DUER_STRLEN(name) + 1);
}
events->_queue = hfmsgq_create(queue_length, sizeof(duer_eq_message));
if (events->_queue == NULL) {
DUER_LOGE("[%s] Create the queue failed!", events->_name);
break;
}
/* for lpb100, lightduer_ca task stack size is 4K */
if (strncmp(name, "lightduer_ca", strlen("lightduer_ca")) == 0) {
stack_size = 4096;
}
hfthread_create(&duer_events_task, name, stack_size / 4, events, duer_priority_get(duer_priority_get_task_id(name)), &(events->_task), NULL);
if (events->_task == NULL) {
DUER_LOGE("[%s] Create the task failed!", events->_name);
break;
}
rs = DUER_OK;
} while (0);
if (rs != DUER_OK) {
duer_events_destroy(events);
events = NULL;
}
return events;
}
int duer_events_call(duer_events_handler handler, duer_events_func func, int what, void *object)
{
int rs = DUER_ERR_FAILED;
duer_events_t *events = (duer_events_t *)handler;
do {
if (events == NULL || events->_queue == NULL) {
break;
}
duer_eq_message message;
message._callback = func;
message._what = what;
message._data = object;
if (HF_SUCCESS != hfmsgq_send(events->_queue, &message, 0, 0)) {
break;
}
rs = DUER_OK;
} while (0);
if (rs < 0 && events != NULL && events->_name != NULL) {
DUER_LOGE("[%s] Queue send failed!", events->_name);
}
return rs;
}
void duer_events_destroy(duer_events_handler handler)
{
duer_events_t *events = (duer_events_t *)handler;
if (events) {
if (events->_task) {
hfthread_destroy(events->_task);
events->_task = NULL;
}
if (events->_queue) {
hfmsgq_destroy(events->_queue);
events->_queue = NULL;
}
if (events->_name) {
DUER_FREE(events->_name);
events->_name = NULL;
}
DUER_FREE(events);
}
}