diff options
Diffstat (limited to 'include/MESA/stream_inc/stream_bridge.h')
| -rw-r--r-- | include/MESA/stream_inc/stream_bridge.h | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/include/MESA/stream_inc/stream_bridge.h b/include/MESA/stream_inc/stream_bridge.h new file mode 100644 index 0000000..3164854 --- /dev/null +++ b/include/MESA/stream_inc/stream_bridge.h @@ -0,0 +1,100 @@ +#ifndef _SAPP_STREAM_BRIDGE_H_ +#define _SAPP_STREAM_BRIDGE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <errno.h> + + +/***************************************** stream bridge API ************************************************* + + stream_bridge_xxx接口用于在不同插件之间, 创建一个通道, 支持同步和异步两种方式互相通信, 支持多对多的关系. + + 同步模式采用callback注册方式, 避免直接使用extern声明函数, 动态、灵活、可扩展. + 异步模式是在streaminfo中保留一份数据, 功能同之前的project_req_xxx系列接口. + + 假设插件plug A,X,Y,Z都注册同一个bridge name:"bridge_demo", bridge_id=1, + + plug A使用异步模式在streaminfo, bridge=1的空间存储了一份数据, receiver X,Y,Z可以在streaminfo生存周期内取数据. + ------------------- + | streaminfo | plug X + |-----------------| / + plug A-->|bridge1 -> data1 |/--plug Y + |-----------------|\ + |bridge2 -> data2 | \ plug Z + |-----------------| + |bridge3 -> data3 | + ------------------- + + + plugA发送一条同步消息, receiver X,Y,Z都可以依次收到. + + -------------------- plug X + | / + plug A ->| bridge_id = 1 /--plug Y + | \ + | \ plug Z + -------------------- + +*******************************************************************************************************************/ + + +/* + bridge_name: 全局唯一, 与之前的project使用不同的命名空间, 可以重名, + 但是bridge_id与project_req_id不能通用!!! + + rw_mode类似fopen函数的参数, 只支持两个模式: + "r": 只读,bridge_name不存在则返回错误; + "w": bridge_name不存在则创建一个新的bridge, + 注意, 如果其他插件已经创建了同名bridge, 再次用"w"模式打开, 不能像fopen以截断模式重新打开一个文件, 其实bridge_id是一样的! + 建议先用"r"模式验证是否有无同名bridge; + + 返回值是bridge_id, + >=0 : success + <0 : error +*/ +int stream_bridge_build(const char *bridge_name, const char *rw_mode); + + +typedef void stream_bridge_free_cb_t(const struct streaminfo *stream, int bridge_id, void *data); +typedef int stream_bridge_sync_cb_t(const struct streaminfo *stream, int bridge_id, void *data); + + +/* + 注意: free函数最多只能有一个, 后面会覆盖前面的函数指针, 多次重复注册只保留最后一个! +*/ +int stream_bridge_register_data_free_cb(int bridge_id, stream_bridge_free_cb_t *free_cb_fun); + +/* sync回调函数可以是多个, 调用stream_bridge_sync_data_put()时, 会调用所有注册的callback函数 */ +int stream_bridge_register_data_sync_cb(int bridge_id, stream_bridge_sync_cb_t *sync_cb_fun); + +/* + 返回值: + 0: 没有stream_bridge_sync_cb_t函数; + -1: error + N: 成功调用stream_bridge_sync_cb_t函数的数量; +*/ +int stream_bridge_sync_data_put(const struct streaminfo *stream, int bridge_id, void *data); + +/* 等同于之前的project_req_add_xxx, 注意如果data是malloc的内存, 要注册stream_bridge_free_cb_t, streaminfo在close时会自动free */ +int stream_bridge_async_data_put(const struct streaminfo *stream, int bridge_id, void *data); + +/* + 返回值: + 非NULL: 插件曾经调用stream_bridge_async_data_put()存储的data值. + NULL : 此时会产生一种歧义, 如果stream_bridge_async_data_put()就是存了一个空指针, 或者利用C的特性, 存了一个整数0, + 如何区别是错误还是原始数据就是0? + + 如果返回值是NULL的情况下, 插件要再判断一下errno, errno == ENODATA (61), 说明确实没有插件曾经存储过数据, 是个错误. +*/ +void *stream_bridge_async_data_get(const struct streaminfo *stream, int bridge_id); /* 等同于之前的project_get_xxx */ + + +#ifdef __cplusplus +} +#endif + +#endif + |
