\r
// erase dead thread\r
if (!m_detachedThreadIds.empty()) {\r
- for (DetachedThreadIds::iterator i = m_detachedThreadIds.begin();\r
+ for (ThreadIds::iterator i = m_detachedThreadIds.begin();\r
i != m_detachedThreadIds.end(); i ++) {\r
FocusOfThreads::iterator j = m_focusOfThreads.find((*i));\r
if (j != m_focusOfThreads.end()) {\r
\r
CHECK_TRUE( CloseHandle(m_readEvent) );\r
m_readEvent = NULL;\r
+\r
+ for (ThreadIds::iterator i = m_attachedThreadIds.begin();\r
+ i != m_attachedThreadIds.end(); i++) {\r
+ PostThreadMessage(*i, WM_NULL, 0, 0);\r
+ }\r
}\r
\r
\r
\r
// remove newly created thread's id from m_detachedThreadIds\r
if (!m_detachedThreadIds.empty()) {\r
- DetachedThreadIds::iterator i;\r
+ ThreadIds::iterator i;\r
bool retry;\r
do {\r
retry = false;\r
}\r
\r
\r
+// thread attach notify\r
+bool Engine::threadAttachNotify(DWORD i_threadId) {\r
+ Acquire a(&m_cs);\r
+ m_attachedThreadIds.push_back(i_threadId);\r
+ return true;\r
+}\r
+\r
+\r
// thread detach notify\r
bool Engine::threadDetachNotify(DWORD i_threadId) {\r
Acquire a(&m_cs);\r
m_detachedThreadIds.push_back(i_threadId);\r
+ m_attachedThreadIds.erase(remove(m_attachedThreadIds.begin(), m_attachedThreadIds.end(), i_threadId),\r
+ m_attachedThreadIds.end());\r
return true;\r
}\r
\r
};\r
typedef std::map<DWORD /*ThreadId*/, FocusOfThread> FocusOfThreads; ///\r
\r
- typedef std::list<DWORD /*ThreadId*/> DetachedThreadIds; ///\r
+ typedef std::list<DWORD /*ThreadId*/> ThreadIds; ///\r
\r
/// current status in generateKeyboardEvents\r
class Current\r
FocusOfThread * volatile m_currentFocusOfThread; ///\r
FocusOfThread m_globalFocus; ///\r
HWND m_hwndFocus; /// current focus window\r
- DetachedThreadIds m_detachedThreadIds; ///\r
+ ThreadIds m_attachedThreadIds; ///\r
+ ThreadIds m_detachedThreadIds; ///\r
\r
// for functions\r
KeymapPtrList m_keymapPrefixHistory; /// for &KeymapPrevPrefix\r
/// sync\r
bool syncNotify();\r
\r
+ /// thread attach notify\r
+ bool threadAttachNotify(DWORD i_threadId);\r
+\r
/// thread detach notify\r
bool threadDetachNotify(DWORD i_threadId);\r
\r
static bool mapHookData(bool i_isYamy);\r
static void unmapHookData();\r
static bool initialize(bool i_isYamy);\r
+static bool notify(void *i_data, size_t i_dataSize);\r
\r
\r
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
g.m_WM_MAYU_MESSAGE =\r
RegisterWindowMessage(addSessionId(WM_MAYU_MESSAGE_NAME).c_str());\r
g.m_hwndTaskTray = g_hookData->m_hwndTaskTray;\r
+ if (!i_isYamy) {\r
+ NotifyThreadAttach ntd;\r
+ ntd.m_type = Notify::Type_threadAttach;\r
+ ntd.m_threadId = GetCurrentThreadId();\r
+ notify(&ntd, sizeof(ntd));\r
+ }\r
g.m_isInitialized = true;\r
return true;\r
}\r
\r
\r
/// notify\r
-DllExport bool notify(void *i_data, size_t i_dataSize)\r
+bool notify(void *i_data, size_t i_dataSize)\r
{\r
COPYDATASTRUCT cd;\r
#ifdef MAYU64\r
Type_name, /// NotifySetFocus\r
Type_lockState, /// NotifyLockState\r
Type_sync, /// Notify\r
+ Type_threadAttach, /// NotifyThreadAttach\r
Type_threadDetach, /// NotifyThreadDetach\r
Type_command64, /// NotifyCommand64\r
Type_command32, /// NotifyCommand32\r
\r
\r
///\r
+struct NotifyThreadAttach : public Notify {\r
+ DWORD m_threadId; ///\r
+};\r
+\r
+\r
+///\r
struct NotifyThreadDetach : public Notify {\r
DWORD m_threadId; ///\r
};\r
break;\r
}\r
\r
+ case Notify::Type_threadAttach: {\r
+ NotifyThreadAttach *n = (NotifyThreadAttach *)cd->lpData;\r
+ m_engine.threadAttachNotify(n->m_threadId);\r
+ break;\r
+ }\r
+\r
case Notify::Type_threadDetach: {\r
NotifyThreadDetach *n = (NotifyThreadDetach *)cd->lpData;\r
m_engine.threadDetachNotify(n->m_threadId);\r
\r
///\r
~Mayu() {\r
- CancelIo(m_hNotifyMailslot);\r
- SleepEx(0, TRUE);\r
- CloseHandle(m_hNotifyMailslot);\r
- CloseHandle(m_hNotifyEvent);\r
- ReleaseMutex(m_mutex);\r
- WaitForSingleObject(m_mutex, INFINITE);\r
- // first, detach log from edit control to avoid deadlock\r
- m_log.detach();\r
-#ifdef LOG_TO_FILE\r
- m_logFile.close();\r
-#endif // LOG_TO_FILE\r
-\r
// stop notify from mayu.dll\r
g_hookData->m_hwndTaskTray = NULL;\r
CHECK_FALSE( uninstallMessageHook() );\r
}\r
CloseHandle(m_hMutexYamyd);\r
#endif // _WIN64\r
- if (!(m_sessionState & SESSION_END_QUERIED)) {\r
- DWORD_PTR result;\r
- SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 3000, &result);\r
- }\r
+\r
+ CancelIo(m_hNotifyMailslot);\r
+ SleepEx(0, TRUE);\r
+ CloseHandle(m_hNotifyMailslot);\r
+ CloseHandle(m_hNotifyEvent);\r
+ ReleaseMutex(m_mutex);\r
+ WaitForSingleObject(m_mutex, INFINITE);\r
+ // first, detach log from edit control to avoid deadlock\r
+ m_log.detach();\r
+#ifdef LOG_TO_FILE\r
+ m_logFile.close();\r
+#endif // LOG_TO_FILE\r
\r
// destroy windows\r
CHECK_TRUE( DestroyWindow(m_hwndVersion) );\r
// stop keyboard handler thread\r
m_engine.stop();\r
\r
+ if (!(m_sessionState & SESSION_END_QUERIED)) {\r
+ DWORD_PTR result;\r
+ SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, 0, 3000, &result);\r
+ }\r
+\r
// remove setting;\r
delete m_setting;\r
}\r
\r
// wait for master process exit\r
WaitForSingleObject(mutex, INFINITE);\r
- ReleaseMutex(mutex);\r
-\r
CHECK_FALSE( uninstallMessageHook() );\r
+ ReleaseMutex(mutex);\r
}\r
\r
return 0;\r