/* ======================================= 工作线程 ======================================= */ CR_API uint_t STDCALL qst_com_main ( __CR_IN__ void_t* param ) { exec_t obj; sQstComm* ctx; /* 加载命令表 */ obj = cmd_exec_init(s_cmdz, cntsof(s_cmdz)); if (obj == NULL) { qst_com_app_exit(param, 0, NULL); return (QST_ERROR); } ctx = (sQstComm*)param; /* 工作循环 */ while (!ctx->quit) { ansi_t* string; /* 接收一条命令 */ /* 即使是出错也要继续运行 */ string = netw_cmd_recv(ctx->netw); if (string == NULL) { thread_sleep(1); continue; } /* 非命令直接交由发送函数处理 */ if (!cmd_type_okay(string) && ctx->comm.thrd != NULL) { if (ctx->comm.send != NULL) { if (ctx->comm.tran == NULL) { /* 直接发送 */ ctx->comm.send(ctx->comm.obj.parm, string, str_lenA(string)); } else { uint_t size; void_t* send; /* 变换后发送 */ send = ctx->comm.tran(string, &size); if (send != NULL) { ctx->comm.send(ctx->comm.obj.parm, send, size); mem_free(send); } } } mem_free(string); continue; } /* 执行这条命令 */ cmd_exec_main(obj, ctx, string); mem_free(string); } /* 等待通讯线程结束 */ if (ctx->comm.thrd != NULL) { ctx->comm.quit = TRUE; thread_wait(ctx->comm.thrd); thread_del(ctx->comm.thrd); } cmd_exec_free(obj); return (QST_OKAY); }
/* --------------------------------------- 关闭通讯接口 --------------------------------------- */ static bool_t qst_com_close ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { sQstComm* ctx; CR_NOUSE(argc); CR_NOUSE(argv); ctx = (sQstComm*)parm; if (ctx->comm.thrd == NULL) return (FALSE); ctx->comm.quit = TRUE; thread_wait(ctx->comm.thrd); thread_del(ctx->comm.thrd); ctx->comm.thrd = NULL; ctx->comm.quit = FALSE; SAFE_FREE(ctx->comm.title); qst_update_title(ctx); CR_VCALL(ctx->bufs)->reput(ctx->bufs, 0); ctx->size = 0; return (TRUE); }
void thread_exit(thread_t * thread) { if (spawn_is_spawned(thread->pid)) spawn_died(thread->pid); thread->state.running = false; thread->state.dead = true; thread_del(thread); }
/* Detach the given thread. The thread must be stopped. The pointer becomes invalid after this call. */ void thread_detach(thread_t * thread) { assert(!thread->state.running); if (likely(ptrace(PTRACE_DETACH, thread->pid, 0, NULL) != -1)) { verbose("Detached %s.", str_thread(thread)); thread_del(thread); } else { thread_handle_ptrace_error(thread, "detaching", errno); } }
/* --------------------------------------- 启动一个工作单元 --------------------------------------- */ static bool_t qst_wrk_wakeup ( __CR_IO__ sQstWork* work, __CR_IN__ ansi_t* name, __CR_IN__ socket_t netw, __CR_IN__ mt_main_t proc ) { thrd_t thrd; uint_t count; /* 查找空闲单元 */ count = work[0].cnt; for (uint_t idx = 0; idx < count; idx++) { if (work[idx].over) { if (!netw_ack_send(netw, TRUE)) return (FALSE); thrd = thread_new(0, proc, &work[idx], TRUE); if (thrd == NULL) return (FALSE); work[idx].name = name; work[idx].netw = netw; work[idx].over = FALSE; if (thread_goon(thrd)) { /* 显示已经连线 */ _ENTER_SHOW_CIN_ printf("[%s] is online.\n", name); _LEAVE_SHOW_CIN_ } thread_del(thrd); return (TRUE); } } netw_ack_send(netw, FALSE); return (FALSE); }
/* ======================================= WinMain 程序入口 ======================================= */ int WINAPI WinMain ( __CR_IN__ HINSTANCE curt_app, __CR_IN__ HINSTANCE prev_app, __CR_IN__ LPSTR cmd_line, __CR_IN__ int cmd_show ) { CR_NOUSE(prev_app); CR_NOUSE(cmd_line); CR_NOUSE(cmd_show); /* 只允许一个例程 */ if (misc_is_running(EXE_XNAME)) return (QST_ERROR); /* 建立 CrHack 系统 */ if (!set_app_type(CR_APP_GUI)) return (QST_ERROR); mem_zero(&s_wrk_ctx, sizeof(s_wrk_ctx)); sint_t x1, y1; uint_t ww, hh; /* 生成一个可变大小的窗口 */ mtlock_init(&s_wrk_ctx.lock); qst_load_cfg(&s_wrk_ctx.cfgs); misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh, QV2D_DEF_WIDTH, QV2D_DEF_HEIGHT); if (ww < QV2D_DEF_WIDTH) ww = QV2D_DEF_WIDTH; if (hh < QV2D_DEF_HEIGHT) hh = QV2D_DEF_HEIGHT; s_wrk_ctx.hwnd = (HWND)window_open(curt_app, (void_t*)WindowProc, x1, y1, ww, hh, WIN_TITLE, WIN_CLASS, (ansi_t*)101, CR_WSTYLE_NORMAL); if (s_wrk_ctx.hwnd == NULL) return (QST_ERROR); SetWindowLongPtr(s_wrk_ctx.hwnd, GWL_STYLE, GetWindowLongPtr(s_wrk_ctx.hwnd, GWL_STYLE) & (~WS_MAXIMIZEBOX)); iGFX2* draw; sIMAGE* imgs; /* 创建 GDI 绘制对象 (只支持32位色屏幕) */ draw = (iGFX2*)create_gdi_canvas(s_wrk_ctx.hwnd, 0, 0, FALSE); if (draw == NULL) { window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS); return (QST_ERROR); } imgs = CR_VCALL(draw)->lock(draw); if (imgs == NULL || imgs->fmt != CR_ARGB8888) { window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS); return (QST_ERROR); } CR_VCALL(draw)->unlock(draw); CR_VCALL(draw)->clear(draw, s_wrk_ctx.cfgs.bkcolor, 0); s_wrk_ctx.draw = draw; /* 初始化网络 */ if (!socket_init()) { window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS); return (QST_ERROR); } s_wrk_ctx.netw = netw_cli_open(EXE_XNAME); if (s_wrk_ctx.netw == NULL) { window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS); return (QST_ERROR); } /* 读取需要超时, 不然线程无法退出 */ socket_set_timeout(s_wrk_ctx.netw, -1, QST_TCP_TOUT); thrd_t thrd; /* 生成工作线程 */ s_wrk_ctx.send = TRUE; s_wrk_ctx.quit = FALSE; s_wrk_ctx.cur_busy = LoadCursor(NULL, IDC_WAIT); s_wrk_ctx.cur_free = LoadCursor(NULL, IDC_ARROW); s_wrk_ctx.res_loader = res_loader_get(); if (s_wrk_ctx.res_loader->init != NULL) s_wrk_ctx.res_loader->init(s_wrk_ctx.netw, NULL); qst_load_filter(&s_wrk_ctx); thrd = thread_new(0, qst_v2d_main, &s_wrk_ctx, FALSE); if (thrd == NULL) { window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS); return (QST_ERROR); } /* 消息循环 */ while (!s_wrk_ctx.quit) { MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { s_wrk_ctx.quit = TRUE; break; } TranslateMessage(&msg); DispatchMessage(&msg); } else { qst_do_keyboard(&s_wrk_ctx); } } thread_wait(thrd); thread_del(thrd); window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS); netw_cli_close(s_wrk_ctx.netw); return (QST_OKAY); }
/* ======================================= WinMain 程序入口 ======================================= */ int WINAPI WinMain ( __CR_IN__ HINSTANCE curt_app, __CR_IN__ HINSTANCE prev_app, __CR_IN__ LPSTR cmd_line, __CR_IN__ int cmd_show ) { uint_t argc; ansi_t** argv; CR_NOUSE(prev_app); CR_NOUSE(cmd_show); /* 只允许一个例程 */ if (misc_is_running(EXE_XNAME)) return (QST_ERROR); /* 建立 CrHack 系统 */ if (!set_app_type(CR_APP_GUI)) return (QST_ERROR); mem_zero(&s_wrk_ctx, sizeof(s_wrk_ctx)); int qt_argc; /* 获取命令行参数, 不包括进程文件名 */ argv = misc_get_param(cmd_line, &argc); qt_argc = (int)argc; QApplication qt_app(qt_argc, argv); qt_app.setApplicationName("QstComm"); qt_app.setOrganizationName("QuestLAB"); sint_t x1, y1; uint_t ww, hh; /* 生成一个可变大小的窗口 */ mtlock_init(&s_wrk_ctx.lock); qst_load_cfg(&s_wrk_ctx.cfgs); misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh, QCOM_DEF_WIDTH, QCOM_DEF_HEIGHT); if (ww < QCOM_DEF_WIDTH) ww = QCOM_DEF_WIDTH; if (hh < QCOM_DEF_HEIGHT) hh = QCOM_DEF_HEIGHT; RECT w_rect; sint_t fw, fh; QMainWindow qt_win; /* Qt 里的宽高都不包括边框 需要自己用 Win32 API 获取 */ qt_win.setWindowFlags(qt_win.windowFlags() & (~Qt::WindowMaximizeButtonHint)); qt_win.move(x1, y1); qt_win.resize(ww, hh); s_wrk_ctx.hwnd = (HWND)qt_win.winId(); if (!GetWindowRect(s_wrk_ctx.hwnd, &w_rect)) return (QST_ERROR); fw = w_rect.right - w_rect.left - ww; fh = w_rect.bottom - w_rect.top - hh; qt_win.setMinimumSize(QCOM_DEF_WIDTH - fw, QCOM_DEF_HEIGHT - fh); qt_win.resize(ww - fw, hh - fh); QWidget* cent = new QWidget (&qt_win); CTextEdit* edit = new CTextEdit (cent); QHBoxLayout* hori = new QHBoxLayout (cent); /* 创建窗体里的控件 */ hori->setSpacing(6); hori->setContentsMargins(8, 8, 8, 8); hori->addWidget(edit); qt_win.setCentralWidget(cent); CTextOper oper(&qt_win, edit); s_wrk_ctx.oper = (void_t*)(&oper); SetClassLongPtr(s_wrk_ctx.hwnd, GCLP_HICON, (LONG_PTR) LoadIconA(curt_app, (ansi_t*)101)); /* 初始化 ANSI 上下文 */ if (!qst_csi_init()) return (QST_ERROR); qst_set_viewer(&s_wrk_ctx); /* 初始化网络 */ if (!socket_init()) return (QST_ERROR); s_wrk_ctx.netw = netw_cli_open(EXE_XNAME); if (s_wrk_ctx.netw == NULL) return (QST_ERROR); /* 读取需要超时, 不然线程无法退出 */ socket_set_timeout(s_wrk_ctx.netw, -1, QST_TCP_TOUT); thrd_t thrd; /* 生成工作线程 */ s_wrk_ctx.quit = FALSE; s_wrk_ctx.comm.quit = FALSE; s_wrk_ctx.comm.text = TRUE; s_wrk_ctx.comm.rtype = "text"; s_wrk_ctx.comm.stype = "text"; s_wrk_ctx.comm.title = NULL; s_wrk_ctx.comm.render = qst_txt_show; s_wrk_ctx.page = get_sys_codepage(); qst_update_title(&s_wrk_ctx); thrd = thread_new(0, qst_com_main, &s_wrk_ctx, FALSE); if (thrd == NULL) return (QST_ERROR); sio_init(); /* 开始 Qt 流程 */ qt_win.show(); qt_app.exec(); /* 关闭线程直接退出 */ if (!s_wrk_ctx.quit) s_wrk_ctx.quit = TRUE; thread_wait(thrd); thread_del(thrd); netw_cli_close(s_wrk_ctx.netw); sio_free(); qst_csi_free(); return (QST_OKAY); }