summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2016-12-12 19:39:45 +0800
committerQiuwen Lu <[email protected]>2016-12-12 19:39:45 +0800
commite5a7bf9cfa911f3b04773e55c81a5354d2d0c6d2 (patch)
tree38c2bd24857ae755344c7cb4b01873a65003b7df
parent83b7454286dd555c5e98bc4667c3fd51653ba3d4 (diff)
增加崩溃检测与回调函数框架
-rw-r--r--app/src/marsio.c12
-rw-r--r--include/internal/mr_common.h8
-rw-r--r--runtime/CMakeLists.txt3
-rw-r--r--runtime/include/mr_runtime.h7
-rw-r--r--runtime/include/runtime.h17
-rw-r--r--runtime/src/app.c25
-rw-r--r--runtime/src/event.c444
-rw-r--r--runtime/src/export.c15
-rw-r--r--runtime/src/runtime.c8
9 files changed, 534 insertions, 5 deletions
diff --git a/app/src/marsio.c b/app/src/marsio.c
index 3c3a875..2b25cb4 100644
--- a/app/src/marsio.c
+++ b/app/src/marsio.c
@@ -154,12 +154,12 @@ static int mrapp_init(const char * appsym, struct mrapp_config * config)
{
// �����
int ret = mrapp_config_check(appsym, config);
- if(ret < 0)
+ if (ret < 0)
{
MR_LOG(ERR, MRLIB, "Marsio config check failed. \n");
return ret;
}
-
+
// Ӧ��ע��
ret = mr_app_register(appsym, config->coremask, config->autoexit);
if (ret < 0)
@@ -168,6 +168,14 @@ static int mrapp_init(const char * appsym, struct mrapp_config * config)
return -1;
}
+ // �������
+ ret = mr_app_crash_raiser_register(appsym);
+ if(ret < 0)
+ {
+ MR_LOG(ERR, MRLIB, "Cannot register application %s crash monitor. \n", appsym);
+ return -2;
+ }
+
MR_LOG(INFO, MRLIB, "Application %s register success. \n", appsym);
// ������̵�Privָ�벻Ϊ�գ�˵����ǰ���й����ָ�������
diff --git a/include/internal/mr_common.h b/include/internal/mr_common.h
index 3911a26..1843002 100644
--- a/include/internal/mr_common.h
+++ b/include/internal/mr_common.h
@@ -116,6 +116,14 @@ static inline const char * __str_errno()
return rte_strerror(rte_errno);
}
+#ifdef __GNUC__
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member) *__mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type,member));})
+#else
+#define container_of(ptr, type,member) \
+ ((type *)((char *)(ptr) - offsetof(type, member)))
+#endif
#ifdef __cplusplus
}
diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
index e2ad0c6..b681298 100644
--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -6,6 +6,7 @@ include_directories(${DPDK_INCLUDE_DIR})
add_definitions(${DPDK_C_PREDEFINED})
include_directories(include)
-add_library(mruntime src/app.c src/ctx.c src/runtime.c src/hwinfo.c src/id.c src/export.c)
+add_library(mruntime src/app.c src/ctx.c src/runtime.c src/hwinfo.c src/id.c
+ src/event.c src/export.c)
target_link_libraries(mruntime PRIVATE rt pthread dl)
target_include_directories(mruntime INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/") \ No newline at end of file
diff --git a/runtime/include/mr_runtime.h b/runtime/include/mr_runtime.h
index 94e27f6..7704e1a 100644
--- a/runtime/include/mr_runtime.h
+++ b/runtime/include/mr_runtime.h
@@ -61,4 +61,9 @@ unsigned int mr_appinfo_get_nr_max_thread(struct appinfo * appinfo);
void * mr_app_priv_get();
void mr_app_priv_set(void * ptr);
void * mr_thread_priv_get();
-void mr_thread_priv_set(void * ptr); \ No newline at end of file
+void mr_thread_priv_set(void * ptr);
+
+typedef void(*app_event_cb_t)(int app_event, const char * appsym,
+ struct appinfo * appinfo, void * arg);
+int mr_app_crash_cb_register(app_event_cb_t cb, void * arg);
+int mr_app_crash_raiser_register(const char * appsym); \ No newline at end of file
diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h
index 744f9d0..5fcc08e 100644
--- a/runtime/include/runtime.h
+++ b/runtime/include/runtime.h
@@ -5,6 +5,8 @@
struct app_manager;
struct hwinfo_manager;
struct id_manager;
+struct app_ev_manager;
+struct appinfo;
#ifndef MR_RUNTIME_MAX_NR_EXIT_HANDLER
#define MR_RUNTIME_MAX_NR_EXIT_HANDLER 64
@@ -16,6 +18,7 @@ struct mr_runtime_ctx
struct app_manager * app_ctx;
struct hwinfo_manager * hwinfo_ctx;
struct id_manager * id_ctx;
+ struct app_ev_manager * ev_ctx;
};
extern struct app_manager * app_manager_create();
@@ -38,6 +41,9 @@ extern int app_manager_appinfo_unregister(struct app_manager * object);
extern int app_manager_thread_register(struct app_manager * object);
extern int app_manager_thread_unregister(struct app_manager * object);
extern int app_manager_appinfo_iterate(struct app_manager * object, struct appinfo ** appinfo);
+extern struct appinfo * app_mamager_appinfo_lookup(struct app_manager * object, const char * appsym);
+extern void app_mamager_crash_event_handler(int app_event, const char * appsym,
+ struct appinfo * appinfo, void * arg);
// ���������������
extern struct id_manager * id_manager_create();
@@ -51,4 +57,13 @@ extern int id_manager_release_gsid(struct id_manager * object, thread_id_t start
extern int mr_global_ctx_init();
extern int mr_global_ctx_slave_init();
extern int mr_global_cfg_init();
-extern int mr_global_cfg_slave_init(); \ No newline at end of file
+extern int mr_global_cfg_slave_init();
+
+// �������
+struct app_ev_manager * app_ev_manager_create(struct mr_runtime_ctx * rt_ctx);
+void app_ev_manager_destory(struct app_ev_manager * object);
+
+typedef void(*app_event_cb_t)(int app_event, const char * appsym, struct appinfo * appinfo, void * arg);
+int app_crash_cb_register(struct app_ev_manager * object, app_event_cb_t cb, void * arg);
+int app_crash_raiser_register(struct app_ev_manager * object, const char * appsym);
+void * app_thread_crash_monitor(void * arg); \ No newline at end of file
diff --git a/runtime/src/app.c b/runtime/src/app.c
index f7e2ac3..ea1980a 100644
--- a/runtime/src/app.c
+++ b/runtime/src/app.c
@@ -457,6 +457,21 @@ int app_manager_appinfo_unregister(struct app_manager * object)
return ret;
}
+#if 0
+typedef void(*app_event_cb_t)(int app_event, const char * appsym,
+ struct appinfo * appinfo, void * arg);
+#endif
+
+void app_mamager_crash_event_handler(int app_event, const char * appsym,
+ struct appinfo * appinfo, void * arg)
+{
+ struct app_manager * object = (struct app_manager *)arg;
+
+ mr_spin_lock(&object->lock);
+ __appinfo_delete_unsafe(object, appinfo);
+ mr_spin_unlock(&object->lock);
+}
+
int app_manager_thread_register(struct app_manager * object)
{
struct appinfo * pinfo = currect_app_info;
@@ -521,6 +536,16 @@ int app_manager_list_all_appinfo(struct app_manager * object,
return ret;
}
+struct appinfo * app_mamager_appinfo_lookup(struct app_manager * object,
+ const char * appsym)
+{
+ struct appinfo * result = NULL;
+ mr_spin_lock(&object->lock);
+ result = __appinfo_lookup_unsafe(object, appsym);
+ mr_spin_unlock(&object->lock);
+ return result;
+}
+
int app_manager_tinfo_iterate(struct appinfo * appinfo,
struct thread_info ** tinfo, int * iterate)
{
diff --git a/runtime/src/event.c b/runtime/src/event.c
new file mode 100644
index 0000000..f27d376
--- /dev/null
+++ b/runtime/src/event.c
@@ -0,0 +1,444 @@
+/* \brief Ӧ�ó����쳣״̬������¼�֪ͨ
+ *
+ * ���Ӧ���쳣�˳�״̬����֪ͨ�����̸�ģ�����Ӧ��ʹ�õ���Դ
+ * TODO: �ع����δ��룬֧�ָ�����첽�ź�֪ͨ����
+ *
+ * \author Qiuwen Lu<[email protected]>
+ * \date 2016-12-09
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/epoll.h>
+#include <assert.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+
+#include <mr_common.h>
+#include <mr_runtime.h>
+#include <runtime.h>
+
+TAILQ_HEAD(crash_ev_raiser_list, crash_ev_raiser);
+TAILQ_HEAD(crash_ev_cb_list, crash_ev_cb);
+
+/* �����¼�Դ */
+struct crash_ev_raiser
+{
+ TAILQ_ENTRY(crash_ev_raiser) next;
+ struct appinfo * appinfo;
+ char appsym[MR_SYMBOL_MAX];
+ int connect_fd;
+};
+
+/* �����¼��������� */
+struct crash_ev_cb
+{
+ TAILQ_ENTRY(crash_ev_cb) next;
+ app_event_cb_t cb;
+ void * arg;
+};
+
+/* �����¼�Դע��ָ�ͨ��TCP���䣩 */
+struct crash_raiser_reg_cmd
+{
+ /* ���� */
+ char symlen;
+ /* ���� */
+ char appsym[MR_SYMBOL_MAX];
+};
+
+struct app_ev_manager
+{
+#define __MAX_CRASH_CBS 64
+
+ /* Rt��� */
+ struct mr_runtime_ctx * rt_ctx;
+ /* Ӧ�ñ����¼�Դ */
+ struct crash_ev_raiser_list crash_ev_raiser_list;
+ /* Ӧ�ñ����¼������ص����� */
+ struct crash_ev_cb_list crash_ev_cb_list;
+ /* Ӧ�ñ�������ַ */
+ struct sockaddr_in crash_sockaddr;
+};
+
+struct app_ev_manager * app_ev_manager_create(struct mr_runtime_ctx * rt_ctx)
+{
+ struct app_ev_manager * object = rte_zmalloc(NULL, sizeof(struct app_ev_manager), 0);
+ MR_CHECK(object != NULL, "Cannot alloc memory for app event manager");
+
+ object->rt_ctx = rt_ctx;
+ TAILQ_INIT(&object->crash_ev_cb_list);
+ TAILQ_INIT(&object->crash_ev_raiser_list);
+ return object;
+}
+
+void app_ev_manager_destory(struct app_ev_manager * object)
+{
+ rte_free(object);
+}
+
+/* ע������������� */
+int app_crash_cb_register(struct app_ev_manager * object, app_event_cb_t cb,
+ void * arg)
+{
+ struct crash_ev_cb * ev_cb = rte_zmalloc(NULL, sizeof(struct crash_ev_cb), 0);
+ MR_CHECK(ev_cb != NULL, "Cannot alloc memory for crash_ev_cb");
+
+ ev_cb->cb = cb;
+ ev_cb->arg = arg;
+ TAILQ_INSERT_TAIL(&object->crash_ev_cb_list, ev_cb, next);
+ return 0;
+}
+
+/* ע������¼�Դ */
+int app_crash_raiser_register(struct app_ev_manager * object, const char * appsym)
+{
+ int conn_fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (unlikely(conn_fd < 0))
+ {
+ MR_LOG(ERR, BASE, "Cannot create socket for crash raiser register : %s. \n",
+ strerror(errno));
+ return -1;
+ }
+
+ int ret = connect(conn_fd, (const struct sockaddr *)&object->crash_sockaddr,
+ sizeof(object->crash_sockaddr));
+
+ if (unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Connect to crash monitor failed : %s", strerror(errno));
+ return -2;
+ }
+
+ struct crash_raiser_reg_cmd reg_cmd;
+ snprintf(reg_cmd.appsym, sizeof(reg_cmd.appsym), "%s", appsym);
+ reg_cmd.symlen = strlen(reg_cmd.appsym);
+
+ do {
+ ret = send(conn_fd, &reg_cmd, sizeof(reg_cmd), MSG_NOSIGNAL);
+ } while (ret == -1 && (errno == EINTR));
+
+ assert(ret == sizeof(reg_cmd));
+ return 0;
+}
+
+/* �¼���������ע��Ӧ�� */
+static int app_crash_handle_new_raiser(struct app_ev_manager * object,
+ const char * appsym, int conn_fd)
+{
+ struct mr_runtime_ctx * rt_ctx = object->rt_ctx;
+ struct app_manager * app_manager = rt_ctx->app_ctx;
+
+ struct appinfo * appinfo = app_mamager_appinfo_lookup(app_manager, appsym);
+ if (appinfo == NULL)
+ {
+ MR_LOG(ERR, BASE, "Application %s does not existed, "
+ "cannot monitor its crash state. \n", appsym);
+ return -1;
+ }
+
+ struct crash_ev_raiser * raiser;
+
+#ifndef _NDEBUG
+ TAILQ_FOREACH(raiser, &object->crash_ev_raiser_list, next)
+ {
+ assert(strcmp(raiser->appsym, appsym) != 0);
+ }
+#endif
+
+ raiser = rte_zmalloc(NULL, sizeof(struct crash_ev_raiser), 0);
+ MR_CHECK(raiser != NULL, "Cannot alloc memory for crash raiser. ");
+
+ snprintf(raiser->appsym, sizeof(raiser->appsym), "%s", appsym);
+ raiser->appinfo = appinfo;
+ raiser->connect_fd = conn_fd;
+ TAILQ_INSERT_TAIL(&object->crash_ev_raiser_list, raiser, next);
+
+ MR_LOG(INFO, BASE, "Crash raiser from application %s registed. \n", appsym);
+ return 0;
+}
+
+/* �¼�������Ӧ�ñ��� */
+static int app_crash_handle_crash_raiser(struct app_ev_manager * object,
+ struct crash_ev_raiser * raiser)
+{
+ MR_LOG(INFO, BASE, "Crash raise from applicaion %s. \n", raiser->appsym);
+
+ struct crash_ev_cb * cb;
+ TAILQ_FOREACH(cb, &object->crash_ev_cb_list, next)
+ {
+ cb->cb(0, raiser->appsym, raiser->appinfo, cb->arg);
+ }
+
+ TAILQ_REMOVE(&object->crash_ev_raiser_list, raiser, next);
+ rte_free(raiser);
+ return 0;
+}
+
+#define __LISTEN_PORT_START 1024
+#define __LISTEN_PORT_END 65535
+#define __LISTEN_BACKEND 16
+
+static int __create_monitor_fd(struct sockaddr_in * sockaddr_in)
+{
+ int try_times_max = 36;
+ int success = 0;
+
+ // �������ض˿ڣ�TCP����
+ int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
+ if(unlikely(listen_fd < 0))
+ {
+ MR_LOG(ERR, BASE, "Create crash monitor listen fd failed : %s. \n",
+ strerror(errno));
+ goto out;
+ }
+
+ int reuse = 1;
+ if (unlikely(setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
+ (const void*)&reuse, sizeof(int)) < 0))
+ {
+ MR_LOG(ERR, BASE, "Set crash monitor listen fd reuse failed : %s\n",
+ strerror(errno));
+ goto out;
+ }
+
+ while (try_times_max >= 0)
+ {
+ unsigned int random_port;
+
+ // ���ѡ��һ�������˿ڣ����ؼ���
+ random_port = rand() % (__LISTEN_PORT_END - __LISTEN_PORT_START) + __LISTEN_PORT_START;
+ assert(random_port >= __LISTEN_PORT_START && random_port <= __LISTEN_PORT_END);
+
+ memset(sockaddr_in, 0, sizeof(struct sockaddr_in));
+ sockaddr_in->sin_family = AF_INET;
+ sockaddr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ sockaddr_in->sin_port = htons(random_port);
+
+ int ret = bind(listen_fd, (struct sockaddr *)sockaddr_in,
+ sizeof(struct sockaddr_in));
+
+ // �˿ڱ�ռ�ã�����ѡ��һ�����õĶ˿�
+ if (ret < 0 && errno == EADDRINUSE)
+ {
+ try_times_max--;
+ continue;
+ }
+
+ // ��������
+ else if (ret < 0)
+ {
+ MR_LOG(ERR, BASE, "Bind crash monitor listen fd(PORT=%d) failed : %s.\n",
+ random_port, strerror(errno));
+ goto out;
+ }
+
+ ret = listen(listen_fd, 20);
+ if(ret < 0)
+ {
+ MR_LOG(ERR, BASE, "Listen crash monitor listen fd(PORT=%d) failed : %s.\n",
+ random_port, strerror(errno));
+ goto out;
+ }
+
+ success = 1;
+ break;
+ }
+
+ if(success)
+ {
+ MR_LOG(INFO, BASE, "Crash monitor listen tcp fd(port=%d) create success.\n",
+ ntohs(sockaddr_in->sin_port));
+ return listen_fd;
+ }
+
+out:
+ if (listen_fd > 0) close(listen_fd);
+ return -1;
+}
+
+#define __EV_MAX_EVENTS 16
+#define __EV_MAX_BUFFER 2048
+
+
+// ���¹��ߺ�����MESATCP�н�ȡ
+static int __tcp_setnonblock(int sockfd)
+{
+ int flags = fcntl(sockfd, F_GETFL, 0);
+ if (flags == -1) return -1;
+ int ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK, 0);
+ if (ret == -1) return -1;
+ return 0;
+}
+
+static int __update_epoll_event(int epoll_fd, int epoll_mode, int fd, int epoll_type)
+{
+ struct epoll_event event = { 0 };
+ event.data.fd = fd;
+ event.events = epoll_type;
+
+ __tcp_setnonblock(fd);
+ if (-1 == epoll_ctl(epoll_fd, epoll_mode, fd, &event))
+ {
+ MR_LOG(ERR, BASE, "update epoll event failed : %s\n",
+ strerror(errno)); return -1;
+ }
+
+ return 0;
+}
+
+int __epoll_add_event(int epoll_fd, int sd, int epoll_type)
+{
+ return __update_epoll_event(epoll_fd, EPOLL_CTL_ADD, sd, epoll_type);
+}
+
+int __epoll_del_event(int epoll_fd, int sd, int epoll_type)
+{
+ return __update_epoll_event(epoll_fd, EPOLL_CTL_DEL, sd, epoll_type);
+}
+
+int __epoll_mod_event(int epoll_fd, int sd, int epoll_type)
+{
+ return __update_epoll_event(epoll_fd, EPOLL_CTL_MOD, sd, epoll_type);
+}
+
+/* �����½��ļ������� */
+void __handle_accept(struct app_ev_manager * object, int epoll_fd, int listen_fd)
+{
+ struct sockaddr_in remote_addr;
+ socklen_t sz_remote_addr = sizeof(remote_addr);
+
+ int conn_fd = accept(listen_fd, (struct sockaddr *)&remote_addr, &sz_remote_addr);
+ if(conn_fd < 0)
+ {
+ MR_LOG(ERR, BASE, "Accept remote connnection failed : %s", strerror(errno));
+ return;
+ }
+
+ __epoll_add_event(epoll_fd, conn_fd, EPOLLIN);
+ return;
+}
+
+// �������ӹر���Ϣ�����ӹرմ���Ӧ�ñ���
+void __handle_close(struct app_ev_manager * object, int epoll_fd, int fd)
+{
+ struct crash_ev_raiser * raiser_iter;
+ TAILQ_FOREACH(raiser_iter, &object->crash_ev_raiser_list, next)
+ {
+ if (raiser_iter->connect_fd != fd) continue;
+ app_crash_handle_crash_raiser(object, raiser_iter);
+ }
+
+ __epoll_del_event(epoll_fd, fd, EPOLLIN);
+ close(fd);
+ return;
+}
+
+/* �����������ӵ�������� */
+void __handle_read(struct app_ev_manager * object, int epoll_fd, int fd)
+{
+ // ���뻺��������������С����ָ���
+ char __read_buffer[sizeof(struct crash_raiser_reg_cmd)];
+ ssize_t __read_buffer_used = 0;
+ ssize_t ret = 0;
+
+ while ((ret = read(fd, __read_buffer + __read_buffer_used,
+ sizeof(__read_buffer) - __read_buffer_used)) > 0)
+ {
+ __read_buffer_used += ret;
+ }
+
+ // ���ݶ���������ָ��
+ if(__read_buffer_used == sizeof(struct crash_raiser_reg_cmd))
+ {
+ struct crash_raiser_reg_cmd * cmd = (struct crash_raiser_reg_cmd *)__read_buffer;
+ if (cmd->symlen != strnlen(cmd->appsym, sizeof(cmd->appsym))) return;
+ app_crash_handle_new_raiser(object, cmd->appsym, fd);
+ return;
+ }
+
+ if(ret < 0 && (errno == EWOULDBLOCK || errno == EAGAIN))
+ {
+ return;
+ }
+
+ if (ret == 0)
+ {
+ __handle_close(object, epoll_fd, fd);
+ return;
+ }
+
+ //TODO: ���������������
+ assert(0);
+ return;
+}
+
+/* ��������߳� */
+//TODO: ���Epoll��ͨ�Ż��ƣ������Libevent��
+
+void * app_thread_crash_monitor(void * arg)
+{
+ struct app_ev_manager * object = (struct app_ev_manager *)arg;
+ pthread_detach(pthread_self());
+
+ int listen_fd = __create_monitor_fd(&object->crash_sockaddr);
+ if(listen_fd < 0)
+ {
+ MR_LOG(ERR, BASE, "Launch crash monitor thread failed : "
+ "Cannot create listen fd. \n"); goto errout;
+ }
+
+ int epoll_fd = epoll_create(16);
+ if(epoll_fd < 0)
+ {
+ MR_LOG(ERR, BASE, "Launch crash monitor thread failed : "
+ "Cannot create epoll fd. \n"); goto errout;
+ }
+
+ struct epoll_event evlist[__EV_MAX_EVENTS];
+ struct epoll_event ev;
+
+ ev.events = EPOLLIN;
+ ev.data.fd = listen_fd;
+ if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) < 0)
+ {
+ MR_LOG(ERR, BASE, "Crash monitor thread failed : "
+ "Add listenfd to epoll list error : %s \n", strerror(errno));
+ goto errout;
+ }
+
+ while(1)
+ {
+ int ret = epoll_wait(epoll_fd, evlist, __EV_MAX_EVENTS, 0);
+ if (ret == -1 && errno == EINTR) continue;
+ else if(ret == -1)
+ {
+ MR_LOG(ERR, BASE, "Crash monitor thread failed : "
+ "waiting on epoll fd : %s", strerror(errno));
+ goto errout;
+ }
+
+ for(int i = 0; i < ret; i++)
+ {
+ int fd = evlist[i].data.fd;
+ if(evlist[i].events & EPOLLIN)
+ {
+ if (fd == listen_fd) __handle_accept(object, epoll_fd, fd);
+ else __handle_read(object, epoll_fd, fd);
+ continue;
+ }
+
+ if(evlist[i].events & ( EPOLLHUP | EPOLLERR))
+ {
+ __handle_close(object, epoll_fd, fd);
+ }
+ }
+ }
+
+errout:
+ MR_LOG(ERR, BASE, "Crash monitor thread is exiting. \n");
+ return (void *)NULL;
+} \ No newline at end of file
diff --git a/runtime/src/export.c b/runtime/src/export.c
index 6a145c3..a4b755a 100644
--- a/runtime/src/export.c
+++ b/runtime/src/export.c
@@ -103,3 +103,18 @@ int mr_id_manager_release_gsid(thread_id_t start_gsid,
struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
return id_manager_release_gsid(rt_ctx->id_ctx, start_gsid, nr_thread);
}
+
+// ������⵼������
+int mr_app_crash_cb_register(app_event_cb_t cb, void * arg)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_crash_cb_register(rt_ctx->ev_ctx, cb, arg);
+}
+
+int mr_app_crash_raiser_register(const char * appsym)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_crash_raiser_register(rt_ctx->ev_ctx, appsym);
+} \ No newline at end of file
diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c
index 37bec21..88e912e 100644
--- a/runtime/src/runtime.c
+++ b/runtime/src/runtime.c
@@ -43,6 +43,14 @@ void mr_runtime_init()
rt_ctx->id_ctx = id_manager_create();
MR_CHECK(rt_ctx->id_ctx != NULL, "RuntimeInit, ID Manager initialize failed. ");
+
+ rt_ctx->ev_ctx = app_ev_manager_create(rt_ctx);
+ MR_CHECK(rt_ctx->ev_ctx != NULL, "RuntimeInit, App event initialize failed. ");
+
+ pthread_t pid_crash_monitor;
+ pthread_create(&pid_crash_monitor, NULL, app_thread_crash_monitor, (void *)rt_ctx->ev_ctx);
+
+ app_crash_cb_register(rt_ctx->ev_ctx, app_mamager_crash_event_handler, rt_ctx->app_ctx);
g_ctx->ctx_runtime = rt_ctx;
return;