void TwitterProto::SignOn(void*) { debugLogA( _T("***** Beginning SignOn process")); WaitForSingleObject(&signon_lock_,INFINITE); // Kill the old thread if it's still around // this doesn't seem to work.. should we wait infinitely? if(hMsgLoop_) { debugLogA( _T("***** Requesting MessageLoop to exit")); QueueUserAPC(APC_callback,hMsgLoop_,(ULONG_PTR)this); debugLogA( _T("***** Waiting for old MessageLoop to exit")); //WaitForSingleObject(hMsgLoop_,INFINITE); WaitForSingleObject(hMsgLoop_,180000); CloseHandle(hMsgLoop_); } if(NegotiateConnection()) // Could this be? The legendary Go Time?? { if(!in_chat_ && db_get_b(0,m_szModuleName,TWITTER_KEY_CHATFEED,0)) OnJoinChat(0,true); SetAllContactStatuses(ID_STATUS_ONLINE); hMsgLoop_ = ForkThreadEx(&TwitterProto::MessageLoop, NULL, 0); } ReleaseMutex(signon_lock_); debugLogA( _T("***** SignOn complete")); }
void FacebookProto::ChangeStatus(void*) { ScopedLock s(signon_lock_); ScopedLock b(facy.buddies_lock_); int new_status = m_iDesiredStatus; int old_status = m_iStatus; if (new_status == ID_STATUS_OFFLINE) { // Logout debugLogA("### Beginning SignOff process"); m_signingOut = true; SetEvent(update_loop_lock_); // Shutdown and close channel handle Netlib_Shutdown(facy.hMsgCon); if (facy.hMsgCon) Netlib_CloseHandle(facy.hMsgCon); facy.hMsgCon = NULL; // Turn off chat on Facebook if (getByte(FACEBOOK_KEY_DISCONNECT_CHAT, DEFAULT_DISCONNECT_CHAT)) facy.chat_state(false); facy.logout(); OnLeaveChat(NULL, NULL); SetAllContactStatuses(ID_STATUS_OFFLINE); ToggleStatusMenuItems(false); delSetting(FACEBOOK_KEY_LOGON_TS); facy.chat_traceid_.clear(); facy.chat_sticky_num_.clear(); facy.chat_sticky_pool_.clear(); facy.chat_msgs_recv_ = 0; facy.chat_req_ = 0; facy.clear_cookies(); facy.clear_notifications(); facy.clear_chatrooms(); facy.clear_readers(); facy.buddies.clear(); facy.messages_ignore.clear(); facy.messages_timestamp.clear(); facy.pages.clear(); facy.typers.clear(); // Clear thread/user id caches? /* Right now it's commented out because it's not really needed to erase - maybe only when user changes login/pass in same account, but even then it shouldn't cause problems facy.thread_id_to_user_id.clear(); facy.chat_id_to_hcontact.clear(); facy.user_id_to_hcontact.clear(); */ // Close connection handle if (facy.hFcbCon) Netlib_CloseHandle(facy.hFcbCon); facy.hFcbCon = NULL; m_iStatus = facy.self_.status_id = ID_STATUS_OFFLINE; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); m_signingOut = false; debugLogA("### SignOff complete"); return; } else if (old_status == ID_STATUS_OFFLINE) { // Login SYSTEMTIME t; GetLocalTime(&t); debugLogA("[%d.%d.%d] Using Facebook Protocol RM %s", t.wDay, t.wMonth, t.wYear, __VERSION_STRING_DOTS); debugLogA("*** Beginning SignOn process"); m_enableChat = getBool(FACEBOOK_KEY_ENABLE_CHATS, DEFAULT_ENABLE_CHATS); m_iStatus = facy.self_.status_id = ID_STATUS_CONNECTING; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); ResetEvent(update_loop_lock_); // Workaround for not working "mbasic." for some users - reset this flag at every login facy.mbasicWorks = true; if (NegotiateConnection() && facy.home() && facy.reconnect()) { // Load all friends ProcessFriendList(NULL); // Process friendship requests ForkThread(&FacebookProto::ProcessFriendRequests, NULL); // Sync threads, get messages - or get unread messages if (getBool(FACEBOOK_KEY_LOGIN_SYNC, DEFAULT_LOGIN_SYNC)) ForkThread(&FacebookProto::SyncThreads, NULL); else ForkThread(&FacebookProto::ProcessUnreadMessages, NULL); // Get notifications ForkThread(&FacebookProto::ProcessNotifications, NULL); // Load pages for post status dialog ForkThread(&FacebookProto::ProcessPages, NULL); // Load on this day posts if (getByte(FACEBOOK_KEY_EVENT_ON_THIS_DAY_ENABLE, DEFAULT_EVENT_ON_THIS_DAY_ENABLE)) ForkThread(&FacebookProto::ProcessOnThisDay, NULL); setDword(FACEBOOK_KEY_LOGON_TS, (DWORD)time(NULL)); ForkThread(&FacebookProto::UpdateLoop, NULL); ForkThread(&FacebookProto::MessageLoop, NULL); if (getByte(FACEBOOK_KEY_SET_MIRANDA_STATUS, DEFAULT_SET_MIRANDA_STATUS)) ForkThread(&FacebookProto::SetAwayMsgWorker, NULL); } else { ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE)old_status, m_iStatus); if (facy.hFcbCon) Netlib_CloseHandle(facy.hFcbCon); facy.hFcbCon = NULL; facy.clear_cookies(); // Set to offline m_iStatus = m_iDesiredStatus = facy.self_.status_id = ID_STATUS_OFFLINE; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); debugLogA("*** SignOn failed"); return; } ToggleStatusMenuItems(true); debugLogA("*** SignOn complete"); } m_invisible = (new_status == ID_STATUS_INVISIBLE); // Remember time of switching to away (and if we are idle already, use the idle time) m_awayTS = (new_status == ID_STATUS_AWAY ? (m_idleTS > 0 ? m_idleTS : ::time(NULL)) : 0); facy.chat_state(!m_invisible); ForkThread(&FacebookProto::ProcessBuddyList, NULL); m_iStatus = facy.self_.status_id = new_status; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); debugLogA("*** ChangeStatus complete"); }