Forráskód Böngészése

Z991239-351 #comment linux下支持通过spshell启动sphost,TODO:实体间通信

gifur 5 éve
szülő
commit
ada0c50c08

+ 17 - 11
Common/SpBase.h

@@ -1247,24 +1247,30 @@ SPBASE_API const char *_GetFileName(const char *pszFilePath);
 extern "C" SPBASE_API void Dbg(const char *str, ...);
 extern "C" SPBASE_API void vDbg(const char *str, va_list list);
 
-/** It is used out of the Entity class members */
-#ifdef _DEBUG
-#define LOG_ASSERT(f) do{if(!(f) && (1 == _CrtDbgReport(_CRT_ASSERT, _GetFileName(__FILE__), __LINE__, NULL, #f))) {_CrtDbgBreak(); LogAssert(#f,_GetFileName(__FILE__), __LINE__);}} while (0)
-#define LOG_ASSERT_MSG(f,pMsg, ...) do{if(!(f) && (1 == _CrtDbgReport(_CRT_ASSERT, _GetFileName(__FILE__), __LINE__, NULL, CSimpleStringA::Format(pMsg, __VA_ARGS__)))) _CrtDbgBreak(); LogAssert(pMsg,_GetFileName(__FILE__), __LINE__);} while (0)
+#if ( ( defined(_DEBUG) && defined(_MSC_VER) ) || (defined(__linux__) && !defined(NDEBUG)) )
 struct CScopeLog
 {
-	CScopeLog(const char *pszMsg, const char *pszFile, int nFileLine) : m_pszMsg(pszMsg), m_pszFile(pszFile), m_nFileLine(nFileLine){Dbg("Enter %s, file: {%s}, line: {%d}", m_pszMsg, m_pszFile, m_nFileLine);}
-	~CScopeLog() {Dbg("Leave %s, file: {%s} ,line: {%d}" , m_pszMsg, m_pszFile, m_nFileLine);}
-	const char *m_pszMsg;
-	const char *m_pszFile;
+	CScopeLog(const char* pszMsg, const char* pszFile, int nFileLine) : m_pszMsg(pszMsg), m_pszFile(pszFile), m_nFileLine(nFileLine) { Dbg("Enter %s, file: {%s}, line: {%d}", m_pszMsg, m_pszFile, m_nFileLine); }
+	~CScopeLog() { Dbg("Leave %s, file: {%s} ,line: {%d}", m_pszMsg, m_pszFile, m_nFileLine); }
+	const char* m_pszMsg;
+	const char* m_pszFile;
 	int m_nFileLine;
 };
 #define LOG_FUNCTION() CScopeLog __FunctionScopeLog(__FUNCTION__, _GetFileName(__FILE__), __LINE__)
-#else//_DEBUG
+#else
+#define LOG_FUNCTION()
+#endif
+//TODO:
+/** It is used out of the Entity class members */
+#if ( (defined(_DEBUG) && defined(_MSC_VER)) )
+#define LOG_ASSERT(f) do{if(!(f) && (1 == _CrtDbgReport(_CRT_ASSERT, _GetFileName(__FILE__), __LINE__, NULL, #f))) {_CrtDbgBreak(); LogAssert(#f,_GetFileName(__FILE__), __LINE__);}} while (0)
+#define LOG_ASSERT_MSG(f,pMsg, ...) do{if(!(f) && (1 == _CrtDbgReport(_CRT_ASSERT, _GetFileName(__FILE__), __LINE__, NULL, CSimpleStringA::Format(pMsg, __VA_ARGS__)))) _CrtDbgBreak(); LogAssert(pMsg,_GetFileName(__FILE__), __LINE__);} while (0)
+
+#else//( (defined(_DEBUG) && defined(_MSC_VER)))
 #define LOG_ASSERT(f) if(!(f)) LogAssert(#f,_GetFileName(__FILE__), __LINE__)
 #define LOG_ASSERT_MSG(f,pMsg, ...) do{ if(!(f)) LogAssert(CSimpleStringA::Format(pMsg, __VA_ARGS__),_GetFileName(__FILE__), __LINE__);} while (0)
-#define LOG_FUNCTION()
-#endif//_DEBUG
+
+#endif// ( (defined(_DEBUG) && defined(_MSC_VER)) )
 #endif // __cplusplus
 
 #endif //_RVC_SPBASE_H_

+ 3 - 1
libtoolkit/CMakeLists.txt

@@ -24,10 +24,12 @@ if(NOT WIN32)
             gettimeofday.c shm.h shm.c
             wavfile.c wavfile.h
             bus-win.c bus_daemon-win.c ioqueue-win.c
+            process_monitor-win.c
         )
 else()
     list(REMOVE_ITEM ${MODULE_PREFIX}_SRCS 
-        bus-unix.c bus_daemon-unix.c ioqueue-unix.c)
+        bus-unix.c bus_daemon-unix.c ioqueue-unix.c
+        process_monitor-unix.c)
 endif()
 #foreach(item ${${MODULE_PREFIX}_SRCS})
 #    message(STATUS ${item})

+ 6 - 6
libtoolkit/bus-unix.c

@@ -754,11 +754,11 @@ static int bus_endpt_poll_internal(bus_endpt_t* endpt, int* result, int timeout)
 			}
 		}
 		else {
-			WLog_ERR(TAG, "is pending now.");
+			//WLog_ERR(TAG, "is pending now.");
 		}
 		// if receive is pending, wait for send or receive complete event
 		if (!pkt) {
-			WLog_DBG(TAG, "wait msg sem or received event. tiemout: %d", timeout);
+			//WLog_DBG(TAG, "wait msg sem or received event. tiemout: %d", timeout);
 			{
 				int nfds;
 				int ret;
@@ -767,7 +767,7 @@ static int bus_endpt_poll_internal(bus_endpt_t* endpt, int* result, int timeout)
 				struct epoll_event* pe;
 				nfds = evtpoll_wait(endpt->ep, events, MAX_EPOLL_EVENT, timeout);
 				if (nfds == 0) {
-					WLog_DBG(TAG, "epoll wait timeout.");
+					//WLog_DBG(TAG, "epoll wait timeout.");
 					return 0; //timeout
 				}
 				if (nfds == -1) {
@@ -1204,7 +1204,7 @@ TOOLKIT_API int bus_endpt_send_msg(bus_endpt_t* endpt, int msg, int nparam, para
 	int rc;
 	uint64_t wdata = 0;
 	assert(endpt);
-	WLog_DBG(TAG, "==> endpt(%d) send msg: %d, %d", endpt->epid, msg, nparam);
+	WLog_DBG(TAG, "==> endpt(%d) send msg: epid %d, param counts %d", endpt->epid, msg, nparam);
 	e.type = msg;
 	e.nparam = nparam;
 	if (nparam) {
@@ -1237,7 +1237,7 @@ TOOLKIT_API int bus_endpt_send_msg(bus_endpt_t* endpt, int msg, int nparam, para
 	if (nparam) {
 		free(e.params);
 	}
-	WLog_DBG(TAG, "<== endpt(%d) send msg: %d, res: %d", endpt->epid, msg, e.evt_result);
+	WLog_DBG(TAG, "<== endpt(%d) send msg: epid %d, evt_res: %d", endpt->epid, msg, e.evt_result);
 	return e.evt_result;
 }
 
@@ -1259,7 +1259,7 @@ TOOLKIT_API int bus_endpt_poll(bus_endpt_t* endpt, int timeout)
 	iobuffer_t* pkt = NULL;
 
 	rc = bus_endpt_poll_internal(endpt, &result, timeout);
-	WLog_DBG(TAG, "bus endpt poll internal: %d, %d", rc, result);
+	//WLog_DBG(TAG, "bus endpt poll internal: %d, %d", rc, result);
 	if (rc > 0) {
 		if (result == BUS_RESULT_DATA) {
 			bus_endpt_recv_pkt(endpt, &epid, &type, &pkt);

+ 1 - 0
libtoolkit/iobuffer.h

@@ -42,6 +42,7 @@ extern "C" {
 #define IOBUF_T_PARAM IOBUF_T_I4
 #endif
 #endif //_WIN32
+#define IOBUF_T_PTR IOBUF_T_PARAM
 
 
 typedef struct iobuffer_t iobuffer_t;

+ 21 - 17
libtoolkit/ioqueue-unix.c

@@ -478,29 +478,32 @@ static int pre_dispatch_network(BOOL* ret, DWORD* dwBytesTransfer, ioqueue_overl
 			ioqueue_tcpsock_t* tcpsock = overlapped->base.handle_ctx;
 			n = 0;
 			for (; n < overlapped->wsabuf.len; ) {
-				nwrite = write(tcpsock->u.sock, overlapped->wsabuf.buf + n, overlapped->wsabuf.len - n);
-				if (nwrite < 0) {
-					if (errno == EAGAIN || errno == EINTR) {
+				do 
+				{
+					nwrite = write(tcpsock->u.sock, overlapped->wsabuf.buf + n, overlapped->wsabuf.len - n);
+
+				} while (nwrite <0 && errno == EINTR);
+				if (nwrite == 0) {
+					WLog_WARN(TAG, "OV_SENDN: remote socket exit.");
+					break;
+				}
+				else if (nwrite < 0) {
+					if (errno == EAGAIN || errno == EWOULDBLOCK) {
 						nwrite = 0;
 					}
 					else {
-						WLog_ERR(TAG, "write error: %d", errno);
-						break;
+						WLog_ERR(TAG, "write error: %s(%d)", strerror(errno), errno);
 					}
-				}
-				else if (nwrite == 0) {
-					WLog_WARN(TAG, "write not specified: %d", errno);
-					//TODO: ¶Ô¶Ë¿ÉÄÜÒѾ­¹Ø±ÕÁË
+					break;
 				}
 				else {
 					n += nwrite;
 				}
 			}
-			if (nwrite < 0) {
-				WLog_WARN(TAG, "write op occurs exception");
-			}
 			WLog_INFO(TAG, "<OV_SENDN>: total_write: %d/%d, cur_send: %d", n, overlapped->wsabuf.len, nwrite);
-			if (ret) *ret = nwrite < 0 ? FALSE : TRUE;
+			if (ret) {
+				*ret = (n == 0 && nwrite <= 0) ? FALSE : TRUE;
+			}
 			if (dwBytesTransfer) *dwBytesTransfer = n;
 			err = 1;
 		}
@@ -530,7 +533,8 @@ static int pre_dispatch_network(BOOL* ret, DWORD* dwBytesTransfer, ioqueue_overl
 				}
 				if (nread == 0) {
 					/*remote socket break*/
-					WLog_WARN(TAG, "remote socket exit.");
+					WLog_WARN(TAG, "OV_RECVN: remote socket exit.");
+					break;
 				} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
 					nread = 0;
 					break;
@@ -540,8 +544,8 @@ static int pre_dispatch_network(BOOL* ret, DWORD* dwBytesTransfer, ioqueue_overl
 				}
 			}
 			WLog_INFO(TAG, "<OV_RECVN>: total_recv: %d/%d, cur_recv: %d", n, overlapped->wsabuf.len, nread);
-			if (ret) {
-				*ret = (n == 0 && n <= nread) ? FALSE : TRUE;
+			if (ret) {//TRUE means correct
+				*ret = (n == 0 && nread <= 0) ? FALSE : TRUE;
 			}
 			if (dwBytesTransfer) *dwBytesTransfer = n;
 			err = 1;
@@ -582,7 +586,7 @@ static int pre_dispatch_network(BOOL* ret, DWORD* dwBytesTransfer, ioqueue_overl
 
 static void dispatch_network(BOOL ret, DWORD dwBytesTransfer, ioqueue_overlapped_t *io_ctx)
 {
-	int err = ret ? 0 : -1;
+	int err = ret ? 0 : -1; //-1 means error
 	ioqueue_base_overlapped_t *base_ov = (ioqueue_base_overlapped_t*)io_ctx;
 	ioqueue_handle_context *handle_ctx = base_ov->handle_ctx;
 

+ 283 - 0
libtoolkit/process_monitor-unix.c

@@ -0,0 +1,283 @@
+#include "precompile.h"
+#include "process_monitor.h"
+#include "list.h"
+#include "spinlock.h"
+#include <assert.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/wlog.h>
+
+#define TAG TOOLKIT_TAG("process_monitor")
+
+#define CMD_REMOVE	0
+#define CMD_ADD		    1
+#define CMD_EXIT	        2
+
+#define EVT_IDX             0
+#define INIT_CNT           1
+
+typedef struct cmd_entry_t 
+{
+	struct list_head entry;
+	int cmd;
+	HANDLE hproc;
+	HANDLE wait_evt;
+	int result;
+}cmd_entry_t;
+
+typedef struct monitor_t 
+{
+	struct list_head entry;
+	HANDLE thread;
+	/*[evt, process_handle1, process_handle2,..., process_handleN] */
+	HANDLE arr_handle[MAXIMUM_WAIT_OBJECTS];
+	int arr_cnt;
+	struct list_head cmd_list;
+	process_monitor_t *parent;
+}monitor_t;
+
+struct process_monitor_t
+{
+	struct list_head full_monitor_list;
+	struct list_head avail_monitor_list;
+	CRITICAL_SECTION lock;
+	process_monitor_on_detect_process_end cb;
+	void *user_data;
+};
+
+static void process_monitor_lock(process_monitor_t *pm)
+{
+	EnterCriticalSection(&pm->lock);
+}
+
+static void process_monitor_unlock(process_monitor_t *pm)
+{
+	LeaveCriticalSection(&pm->lock);
+}
+
+static unsigned int __stdcall monitor_thread_proc(void *arg)
+{
+	monitor_t *monitor = (monitor_t*)arg;
+
+	for (;;) {
+		DWORD dwRet = WaitForSingleObject(monitor->arr_handle[0], 500);
+		int i;
+		if (dwRet == WAIT_OBJECT_0) {
+			cmd_entry_t* cmd = list_first_entry(&monitor->cmd_list, cmd_entry_t, entry);
+			list_del(&cmd->entry);
+			if (cmd->cmd == CMD_ADD) {
+				monitor->arr_handle[monitor->arr_cnt++] = cmd->hproc;
+				cmd->result = 0;
+				if (cmd->wait_evt)
+					SetEvent(cmd->wait_evt);
+			}
+			else if (cmd->cmd == CMD_REMOVE) {
+				int i;
+				cmd->result = -1;
+				for (i = 0; i < monitor->arr_cnt; ++i) {
+					if (monitor->arr_handle[i] == cmd->hproc) {
+						if (i != monitor->arr_cnt - 1) {
+							monitor->arr_handle[i] = monitor->arr_handle[monitor->arr_cnt - 1];
+						}
+						monitor->arr_cnt--;
+						cmd->result = 0;
+						break;
+					}
+				}
+				if (cmd->wait_evt)
+					SetEvent(cmd->wait_evt);
+			}
+			else if (cmd->cmd == CMD_EXIT) {
+				cmd->result = 0;
+				if (cmd->wait_evt)
+					SetEvent(cmd->wait_evt);
+				break;
+			}
+			else {
+				cmd->result = -1;
+				if (cmd->wait_evt)
+					SetEvent(cmd->wait_evt);
+			}
+		}
+		else if (dwRet != WAIT_TIMEOUT) {
+			WLog_ERR(TAG, "WaitForSingleObject failed!");
+			abort();
+		}
+		for (i = 1; i < monitor->arr_cnt; ++i) {
+			dwRet = WaitForSingleObject(monitor->arr_handle[i], 0);
+			if (dwRet == WAIT_OBJECT_0) {
+				int idx = i;
+				HANDLE hProc = monitor->arr_handle[idx];
+				WLog_DBG(TAG, "process exit, execute callback!");
+				if ((*monitor->parent->cb)(monitor->parent, hProc, monitor->parent->user_data)) {
+					if (monitor->arr_handle[idx] == hProc) {
+						if (idx != monitor->arr_cnt - 1)
+							monitor->arr_handle[idx] = monitor->arr_handle[monitor->arr_cnt - 1];
+						monitor->arr_cnt--;
+					}
+					else {
+						assert(false);
+					}
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+TOOLKIT_API int process_monitor_add(process_monitor_t *monitor, tk_process_t* process)
+{
+	cmd_entry_t ce;
+	monitor_t *m = NULL;
+
+	assert(monitor);
+	assert(process != NULL);
+
+	ce.wait_evt = CreateEventA(NULL, FALSE, FALSE, NULL);
+	if (!ce.wait_evt)
+		return -1;
+	ce.cmd = CMD_ADD;
+	ce.hproc = process->handle;
+
+	process_monitor_lock(monitor);
+	if (list_empty(&monitor->avail_monitor_list)) {
+		m = MALLOC_T(monitor_t);
+		if(m == NULL) {
+			return -1;
+		}
+		m->arr_cnt = INIT_CNT;
+		/*
+		 *The state of a semaphore is signaled when its count is greater than zero
+		 *the count is increased by a specified amount by calling ReleaseSemaphore.
+		 */
+		m->arr_handle[EVT_IDX] = CreateSemaphoreA(NULL, 0, 0x7fffffff, NULL);
+		if (!m->arr_handle[EVT_IDX]) {
+			free(m);
+			process_monitor_unlock(monitor);
+			return -1;
+		}
+		m->parent = monitor;
+		m->thread = (HANDLE)_beginthreadex(NULL, 0, &monitor_thread_proc, m, 0, NULL);
+		if (!m->thread) {
+			CloseHandle(m->arr_handle[EVT_IDX]);
+			free(m);
+			process_monitor_unlock(monitor);
+			return -1;
+		}
+		INIT_LIST_HEAD(&m->cmd_list);
+		/*only one elem at current time*/
+		list_add_tail(&m->entry, &monitor->avail_monitor_list);
+	} else {
+		/*get the existed elem*/
+		m = list_first_entry(&monitor->avail_monitor_list, monitor_t, entry);
+	}
+	list_add_tail(&ce.entry, &m->cmd_list);
+	ReleaseSemaphore(m->arr_handle[EVT_IDX], 1, NULL);
+	/*wait CMD_ADD cmd result.*/
+	WaitForSingleObject(ce.wait_evt, INFINITE);
+	if (m->arr_cnt == MAXIMUM_WAIT_OBJECTS) {
+		list_del(&m->entry);
+		list_add_tail(&m->entry, &monitor->full_monitor_list);
+	}
+	process_monitor_unlock(monitor);
+	CloseHandle(ce.wait_evt);
+	WLog_DBG(TAG, "process monitor add: %d", ce.result);
+	return ce.result;
+}
+
+TOOLKIT_API int process_monitor_remove(process_monitor_t *monitor, tk_process_t* process)
+{
+	cmd_entry_t ce;
+
+	assert(monitor);
+	assert(process);
+
+	ce.wait_evt = CreateEventA(NULL, FALSE, FALSE, NULL);
+	if (!ce.wait_evt)
+		return -1;
+	ce.cmd = CMD_REMOVE;
+	ce.hproc = process->handle;
+	ce.result = -1;
+
+	process_monitor_lock(monitor);
+	{
+		monitor_t *pos;
+		list_for_each_entry(pos, &monitor->full_monitor_list, monitor_t, entry) {
+			list_add_tail(&ce.entry, &pos->cmd_list);
+			ReleaseSemaphore(pos->arr_handle[EVT_IDX], 1, NULL);
+			WaitForSingleObject(ce.wait_evt, INFINITE);
+			if (ce.result == 0) {
+				list_del(&pos->entry);
+				list_add_tail(&pos->entry, &monitor->avail_monitor_list);
+				break;
+			}
+		}
+		if (ce.result == -1) {
+			list_for_each_entry(pos, &monitor->avail_monitor_list, monitor_t, entry) {
+				list_add_tail(&ce.entry, &pos->cmd_list);
+				ReleaseSemaphore(pos->arr_handle[EVT_IDX], 1, NULL);
+				WaitForSingleObject(ce.wait_evt, INFINITE);
+				if (ce.result == 0) {
+					break;
+				}
+			}
+		}
+	}
+	process_monitor_unlock(monitor);
+	CloseHandle(ce.wait_evt);
+	WLog_DBG(TAG, "process monitor remove: %d", ce.result);
+	return ce.result;
+}
+
+TOOLKIT_API int process_monitor_create(process_monitor_t **p_monitor)
+{
+	process_monitor_t *pm = MALLOC_T(process_monitor_t);
+	INIT_LIST_HEAD(&pm->full_monitor_list);
+	INIT_LIST_HEAD(&pm->avail_monitor_list);
+	InitializeCriticalSection(&pm->lock);
+	pm->cb = NULL;
+	*p_monitor = pm;
+	return 0;
+}
+
+TOOLKIT_API int process_monitor_destroy(process_monitor_t *monitor)
+{
+	int i;
+	struct list_head *lists[] = {&monitor->avail_monitor_list, &monitor->full_monitor_list};
+	for (i = 0; i < array_size(lists); ++i) {
+		monitor_t *pos, *n;
+		list_for_each_entry_safe(pos, n, lists[i], monitor_t, entry) {
+			cmd_entry_t ce;
+			ce.cmd = CMD_EXIT;
+			ce.wait_evt = NULL;
+			list_add_tail(&ce.entry, &pos->cmd_list);
+			ReleaseSemaphore(pos->arr_handle[EVT_IDX], 1, NULL);
+			WaitForSingleObject(pos->thread, INFINITE);
+			list_del(&pos->entry);
+			CloseHandle(pos->thread);
+			CloseHandle(pos->arr_handle[EVT_IDX]);
+			free(pos);
+		}
+	}
+	DeleteCriticalSection(&monitor->lock);
+	free(monitor);
+	return 0;
+}
+
+TOOLKIT_API int process_monitor_set_cb(process_monitor_t *monitor, process_monitor_on_detect_process_end cb, void *user_data)
+{
+	monitor->cb = cb;
+	monitor->user_data = user_data;
+	return 0;
+}
+
+TOOLKIT_API int process_monitor_start(process_monitor_t *monitor)
+{
+	return 0;
+}
+
+TOOLKIT_API int process_monitor_stop(process_monitor_t *monitor)
+{
+	return 0;
+}

+ 0 - 0
libtoolkit/process_monitor.c → libtoolkit/process_monitor-win.c


+ 4 - 4
spbase/SpBase.cpp

@@ -204,13 +204,13 @@ extern "C" SPBASE_API void vDbg(const char *str, va_list list)
 
 	char *buf = (char*)_alloca(n+1);
 	memset(buf, 0, n+1);
-	vsnprintf(buf, n, str, list);
-
-
-	SpModule *pModule = GetSpModule();
+	/*write at most n bytes(including the terminating null byte '\0') to buf*/
+	vsnprintf(buf, n+1, str, list); // plus 1 to n, never changed code but the log lost one char [4/1/2020 16:25 Gifur]
+	
 	sp_dbg_debug("Debug: {%s}", buf);	//打印到文件
 	
 	//修改,不发出Log_Debug类消息
+	//SpModule* pModule = GetSpModule();
 // 	if (pModule)
 // 	{
 // 		__try

+ 2 - 1
spbase/SpEntity.cpp

@@ -378,8 +378,10 @@ void SpEntity::on_entity_redirect_subscribe(sp_uid_t *uid, int from_entity_id, c
 
 void SpEntity::__on_entity_prestart(sp_mod_entity_stub_t *, int trigger_entity_id, int argc, char *argv[], void *user_data)
 {
+	sp_dbg_debug("==> %s", __FUNCTION__);
 	SpEntity *pThis = static_cast<SpEntity*>(user_data);
 	pThis->on_entity_prestart(trigger_entity_id, argc, argv);
+	sp_dbg_debug("<== %s", __FUNCTION__);
 }
 
 void SpEntity::__on_entity_stop(sp_mod_entity_stub_t *, int trigger_entity_id, int cause_code, void *user_data)
@@ -454,7 +456,6 @@ int SpEntity::on_accept(int epid, int svc_id, int conn_id, iobuffer_t **conn_pkt
 	} 
 	else
 	{
-		// �ض���
 		if (m_redirect_entity_cache) 
 		{
 			*redirect_entity_id = m_redirect_entity_cache->cfg->idx;

+ 5 - 2
spbase/sp_iom.c

@@ -406,7 +406,8 @@ int sp_iom_send(sp_iom_t *iom, int this_svc_id, int epid, int svc_id, int pkt_ty
 {
 	iobuffer_t *pkt = p_pkt ? *p_pkt : NULL;
 	int rc;
-
+	sp_dbg_debug("== > sp_iom_send: pkt type: %d, this_svc id: %d, epid:%d, svc id:%d, pkt_id: %d",
+		pkt_type, this_svc_id, epid, svc_id, pkt_id);
 	if (!pkt) {
 		pkt = iobuffer_create(-1, -1);
 	}
@@ -420,6 +421,7 @@ int sp_iom_send(sp_iom_t *iom, int this_svc_id, int epid, int svc_id, int pkt_ty
 			pkt_id,
 			(param_size_t)pkt,
 		};
+
 		rc = bus_endpt_send_msg(iom->endpt, IOM_T_SEND_INFO, array_size(params), params);
 	}
 
@@ -434,7 +436,8 @@ int sp_iom_send(sp_iom_t *iom, int this_svc_id, int epid, int svc_id, int pkt_ty
 
 	if (rc != 0)
 		rc = Error_IO;
-
+	sp_dbg_debug("<== sp_iom_send: pkt type: %d, this_svc id: %d, epid:%d, svc id:%d, pkt_id: %d, rc=%d!",
+		pkt_type, this_svc_id, epid, svc_id, pkt_id, rc);
 	return rc;
 }
 

+ 28 - 7
spbase/sp_mod.c

@@ -151,14 +151,16 @@ static void mod_entity_process_cmd(threadpool_t *threadpool, void *arg)
 	int pkt_type;
 	int pkt_id;
 	int cmd_type;
-
-	iobuffer_read(pkt, IOBUF_T_I4, &stub, NULL);
+	sp_dbg_debug("==> %s", __FUNCTION__);
+	iobuffer_read(pkt, IOBUF_T_PTR, &stub, NULL);
 	iobuffer_read(pkt, IOBUF_T_I4, &epid, NULL);
 	iobuffer_read(pkt, IOBUF_T_I4, &svc_id, NULL);
 	iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, NULL);
 	iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, NULL);
-
+	sp_dbg_debug("receive stub address: intptr 0x%016X", (intptr_t)stub);
+	sp_dbg_debug("receive stub address: int 0x%016X", (int)stub);
 	cmd_type = SP_GET_TYPE(pkt_type);
+	sp_dbg_debug("enter mod entity process cmd: %d", cmd_type);
 
 	switch (cmd_type) {
 		case MOD_CMD_TEST:
@@ -213,7 +215,9 @@ static void mod_entity_process_cmd(threadpool_t *threadpool, void *arg)
 					str_parse_cmdline(cmdline, (char **)p, p + numargs * sizeof(char *), &numargs, &numchars);
 				}
 				iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
+				sp_dbg_debug("before invoke on_entity_prestart(trigger %d)", trigger_entity_id);
 				stub->cb.on_entity_prestart(stub, trigger_entity_id, argc, argv, stub->cb.user_data);
+				sp_dbg_debug("after invoke on_entity_prestart(trigger %d)", trigger_entity_id);
 				free(p);
 				free(cmdline);
 			}
@@ -262,7 +266,9 @@ static int mod_entity_on_pkt(sp_svc_t *svc, int epid, int svc_id, int pkt_type,
 				iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_type, 0);
 				iobuffer_write_head(pkt, IOBUF_T_I4, &svc_id, 0);
 				iobuffer_write_head(pkt, IOBUF_T_I4, &epid, 0);
-				iobuffer_write_head(pkt, IOBUF_T_I4, &stub, 0);
+				iobuffer_write_head(pkt, IOBUF_T_PTR, &stub, 0);
+				sp_dbg_debug("stub address: intptr 0x%016X", (intptr_t)stub);
+				sp_dbg_debug("stub address: int 0x%016X", (int)stub);
 				threadpool_queue_workitem(sp_svc_get_threadpool(stub->svc), stub->strand, &mod_entity_process_cmd, pkt);
 				return FALSE;
 		}
@@ -1621,7 +1627,7 @@ static int load_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
 #endif //_WIN32
 
 	if (rc == 0) {
-		const int interval = 50;
+		const int interval = 50; //consider sleep operation below, here would consume 4 min at terriable situation.
 		const int tries = PROCESS_TIMEOUT / interval;
 		int i;
 
@@ -1657,8 +1663,18 @@ static int load_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
 		} else {
 			sp_dbg_info("send out mod init cmd ok!, %s", mod->cfg->name);
 			for (i = 0; i < tries; ++i) {
-				HANDLE hs[] = {mod->evt_wait_handle, mod->process.handle};	//wait for entity thread end
+#ifdef _WIN32
+				HANDLE hs[] = { mod->evt_wait_handle, mod->process.handle };	//wait for entity thread end
 				DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, (DWORD)interval);
+#else
+				DWORD dwRet = WaitForSingleObject(mod->evt_wait_handle, (DWORD)interval);
+				if (dwRet == WAIT_TIMEOUT) {
+					dwRet = WaitForSingleObject(mod->process.handle, 0);
+					if (dwRet == WAIT_OBJECT_0) {
+						dwRet = WAIT_OBJECT_0 + 1;
+					}
+				}
+#endif //_WIN32
 				if (dwRet == WAIT_OBJECT_0) {
 					sp_dbg_info("receive reply from module %s ok!", mod->cfg->name);
 					rc = mod->wait_result;
@@ -1667,9 +1683,14 @@ static int load_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
 					sp_dbg_debug("detect process %s exit exception!", mod->cfg->name);
 					rc = Error_Unexpect;
 					break;
-				} else {
+				} else if(dwRet == WAIT_TIMEOUT){
 					rc = Error_TimeOut;
 				}
+				else {
+					sp_dbg_error("wait for multi object failed!! err=%d", GetLastError());
+					rc = Error_Unexpect;
+					break;
+				}
 			}
 		}
 	}

+ 1 - 1
spbase/sp_mod.h

@@ -133,7 +133,7 @@ struct sp_entity_t
 	sp_cfg_shell_entity_t *cfg;
 	int instance_id;
 	int wait_result;
-	HANDLE evt_wait_handle;
+	HANDLE evt_wait_handle; //manually
 	sp_mod_t *mod;
 	int user_state;
 };

+ 6 - 0
test/module/mod_helloservice/mod_helloservice.cpp

@@ -50,6 +50,12 @@ public:
 		LogEvent(Severity_Middle, 0x20300001, "hello service test");
 	}
 
+	void OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
+	{
+		LOG_FUNCTION();
+		pTransactionContext->SendAnswer(Error_Succeed); 
+	}
+
 	virtual void OnStarted()
 	{
 		LOG_FUNCTION();

+ 9 - 4
winpr/libwinpr/synch/wait.c

@@ -283,6 +283,11 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
 			if (ret == 0) {
 				return WAIT_TIMEOUT;
 			}
+			else if (ret != process->pid) {
+				WLog_ERR(TAG, "waitpid failure [%d] %s", errno, strerror(errno));
+				SetLastError(ERROR_INTERNAL_ERROR);
+				return WAIT_FAILED;
+			}
 		}
 		else {
 			struct timespec timeout;
@@ -449,15 +454,15 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
 		{
 			if (bWaitAll)
 			{
-				if (signalled_idx[index])
+				if (signalled_idx[index]) /*has been signaled?*/
 					continue;
 
-				poll_map[polled] = index;
+				poll_map[polled] = index; /*to listern?*/
 			}
 
 			if (!winpr_Handle_GetInfo(lpHandles[index], &Type, &Object))
 			{
-				WLog_ERR(TAG, "invalid event file descriptor at WaitForMultipleObjects");
+				WLog_ERR(TAG, "invalid event file descriptor at WaitForMultipleObjects[%d]", index);
 				SetLastError(ERROR_INVALID_HANDLE);
 				return WAIT_FAILED;
 			}
@@ -466,7 +471,7 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
 
 			if (fd == -1)
 			{
-				WLog_ERR(TAG, "invalid file descriptor at WaitForMultipleObjects");
+				WLog_ERR(TAG, "invalid file descriptor at WaitForMultipleObjects[%d]", index);
 				SetLastError(ERROR_INVALID_HANDLE);
 				return WAIT_FAILED;
 			}

+ 8 - 8
winpr/libwinpr/thread/process.c

@@ -468,6 +468,7 @@ BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode)
 	if (kill(process->pid, SIGTERM))
 		return FALSE;
 
+	WLog_WARN(TAG, "%s: uExitCode not used!", __FUNCTION__);
 	return TRUE;
 }
 
@@ -497,8 +498,7 @@ static int ProcessGetFd(HANDLE handle)
 
 	if (!ProcessHandleIsHandle(handle))
 		return -1;
-
-	/* TODO: Process does not support fd... */
+	WLog_ERR(TAG, "TODO: Process does not support fd...");
 	(void)process;
 	return -1;
 }
@@ -547,7 +547,7 @@ int _spawnl(int mode, char const* fileName, const char * arguments, ...)
 	int pid = fork();
 	if (pid < 0) {
 		/*fork failed.*/
-		fprintf(stderr, "fork failed.\n");
+		WLog_ERR(TAG, "fork failed.");
 		return -1;
 	}
 	if (pid == 0) {
@@ -569,11 +569,11 @@ int _spawnl(int mode, char const* fileName, const char * arguments, ...)
 			}
 		}
 		exe_argvs[count] = NULL;
-		printf("argv counts: %d\n", count);
+		WLog_DBG(TAG, "argv counts: %d", count);
 		va_end(args);
 		res = execv(fileName, exe_argvs);
 		if (res == -1) {
-			fprintf(stderr, "execl failed: %s\n", strerror(errno));
+			WLog_ERR(TAG, "execl failed: %s", strerror(errno));
 			_exit(1);
 		}
 	}
@@ -589,16 +589,16 @@ int _spawnl(int mode, char const* fileName, const char * arguments, ...)
 				}
 			}
 			if (res2 != pid) {
-				fprintf(stderr, "waitpid failed: %s\n", strerror(errno));
+				WLog_ERR(TAG, "waitpid failed: %s(%d)", strerror(errno), errno);
 				status = -1;
 			}
 			else {
 				if (WIFEXITED(status) != 0) {
 					status = WEXITSTATUS(status);
-					printf("normal terminate: value:%d\n", status);
+					WLog_DBG(TAG, "normal terminate: value:%d", status);
 				}
 				else {
-					printf("unpexct terminate: value:%d\n", status);
+					WLog_DBG(TAG, "unpexct terminate: value:%d", status);
 				}
 			}
 		}