Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions RimeWithWeasel/RimeWithWeasel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,18 @@ void RimeWithWeaselHandler::Initialize() {

LOG(INFO) << "Initializing la rime.";
rime_api->initialize(NULL);
if (rime_api->start_maintenance(/*full_check = */ False)) {
m_disabled = true;
HANDLE hMutex =
CreateMutexW(NULL, FALSE, L"Global\\WeaselStartMaintenanceMutex");
if (hMutex) {
if (WaitForSingleObject(hMutex, 0) == WAIT_OBJECT_0) {
if (rime_api->start_maintenance(/*full_check = */ False)) {
rime_api->join_maintenance_thread();
m_disabled = true;
}
ReleaseMutex(hMutex);
}
CloseHandle(hMutex);
}

RimeConfig config = {NULL};
if (rime_api->config_open("weasel", &config)) {
if (m_ui) {
Expand Down
18 changes: 17 additions & 1 deletion WeaselServer/WeaselServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,23 @@ int WINAPI _tWinMain(HINSTANCE hInstance,

hRes = _Module.Init(NULL, hInstance);
ATLASSERT(SUCCEEDED(hRes));

HANDLE hMutex =
OpenMutexW(SYNCHRONIZE, FALSE, L"Global\\WeaselStartMaintenanceMutex");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

發生了什麼事?
算法服務進程不是只能運行一個實例嗎。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这还没有到原来的mutex位置,比如/q参数的执行就不会运行到那个单实例的位置

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/q 让当前实例以 client 身份向正在运行的算法服务进程发信,那就不需要因为 start_maintenance 互斥吧。加了锁,会不会反而不能发信让主进程退出了?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/q 让当前实例以 client 身份向正在运行的算法服务进程发信,那就不需要因为 start_maintenance 互斥吧。加了锁,会不会反而不能发信让主进程退出了?

目前试的状态是如果服务正在做start_maintenance,会堵塞住不响应其他业务。因此这个pr是要在start_maintenance 的时候标记mutex,其他尝试这种时候ipc通信的情况直接短路跳过,避免客户端堵塞卡死。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好像是,有這個問題。
因爲在主線程等待嗎?

我認爲比較理想的修改是像用戶主動發起的部署過程一樣,算法服務能夠回應 IPC,返回「維護中」的狀態。

start_maintenance 有回調,weaselserver 應該有機會設置「維護中」的 Mutex。這條路竟然沒走通嗎。
看來是因爲主線程在等待部署結束,還不能處理 IPC 的原因。再研究研究。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

大概就是 join_maintenance_thread 造成的。
阻塞式初始化部署的目的是讓第一次按鍵就能出字;因爲通常軟件安裝時 SharedData 已經有部署好的詞典,這次初始部署很快,用戶能等。

小狼毫的情況又有所不同,安裝過程中已經在 UserData 做了部署,理論上已經能保證第一次按鍵時,輸入法的數據可用。初始部署是不是可以不等待,直接進入 IPC 循環?如果真的配置變化,就處於「維護中」狀態。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

潜在可能有一种情况,用户未知方式修改了方案,然后未知原因的服务退出,这个时候前端尝试拉起服务会卡住(部署堵塞)。试过不join thread,那就算加了mutex都避不了卡。在回调里处理mutex和init里处理效果一样

if (hMutex) {
DWORD wr = WaitForSingleObject(hMutex, 0);
if (wr == WAIT_TIMEOUT) {
CloseHandle(hMutex);
return 0;
}
if (wr == WAIT_OBJECT_0 || wr == WAIT_ABANDONED) {
ReleaseMutex(hMutex);
}
CloseHandle(hMutex);
}
if (hMutex) {
ReleaseMutex(hMutex);
CloseHandle(hMutex);
}
if (!wcscmp(L"/userdir", lpstrCmdLine)) {
CreateDirectory(WeaselUserDataPath().c_str(), NULL);
WeaselServerApp::explore(WeaselUserDataPath());
Expand Down
14 changes: 14 additions & 0 deletions WeaselTSF/WeaselTSF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,20 @@ void WeaselTSF::_Reconnect() {
static unsigned int retry = 0;

bool WeaselTSF::_EnsureServerConnected() {
// if maintenancing, return false
HANDLE hMutex =
OpenMutexW(SYNCHRONIZE, FALSE, L"Global\\WeaselStartMaintenanceMutex");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建立連接也需要檢查嗎?

算法服務中持續較長時間的維護工作處於單獨的線程,主線程仍可處理與前端的通信。
應該可以建立連接,並讓前端獲知算法服務處於維護模式。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

试过似乎是不行的,所以才每次都耗些微秒来检查这个

if (hMutex) {
DWORD wr = WaitForSingleObject(hMutex, 0);
if (wr == WAIT_TIMEOUT) {
CloseHandle(hMutex);
return false;
}
if (wr == WAIT_OBJECT_0 || wr == WAIT_ABANDONED) {
ReleaseMutex(hMutex);
}
CloseHandle(hMutex);
}
if (!m_client.Echo()) {
_Reconnect();
retry++;
Expand Down