void Logger::log(bool err, const std::string &msg, const StackTrace *stackTrace, bool escape /* = true */, bool escapeMore /* = false */) { ASSERT(!escapeMore || escape); ThreadData *threadData = s_threadData.get(); if (++threadData->message > MaxMessagesPerRequest && MaxMessagesPerRequest >= 0) { return; } boost::shared_ptr<StackTrace> deleter; if (stackTrace == NULL) { deleter = boost::shared_ptr<StackTrace>(new StackTrace()); stackTrace = deleter.get(); } if (UseLogAggregator) { LogAggregator::TheLogAggregator.log(*stackTrace, msg); } FILE *stdf = err ? stderr : stdout; if (UseLogFile) { FILE *f; if (UseCronolog) { f = cronOutput.getOutputFile(); if (!f) f = stdf; } else { f = Output ? Output : stdf; } string header, sheader; if (LogHeader) { header = GetHeader(); if (LogNativeStackTrace) { sheader = header + "[" + stackTrace->hexEncode(5) + "] "; } else { sheader = header; } } const char *escaped = escape ? EscapeString(msg) : msg.c_str(); const char *ending = escapeMore ? "\\n" : "\n"; int bytes; if (f == stdf && Util::s_stderr_color) { bytes = fprintf(f, "%s%s%s%s%s", Util::s_stderr_color, sheader.c_str(), msg.c_str(), ending, ANSI_COLOR_END); } else { bytes = fprintf(f, "%s%s%s", sheader.c_str(), escaped, ending); } atomic_add(bytesWritten, bytes); FILE *tf = threadData->log; if (tf) { threadData->bytesWritten += fprintf(tf, "%s%s%s", header.c_str(), escaped, ending); fflush(tf); checkDropCache(threadData->bytesWritten, threadData->prevBytesWritten, tf); } if (threadData->hook) { threadData->hook(header.c_str(), msg.c_str(), ending, threadData->hookData); } if (escape) { free((void*)escaped); } fflush(f); if (UseCronolog || (Output && RuntimeOption::LogFile[0] != '|')) { checkDropCache(bytesWritten, prevBytesWritten, f); } } }
void* run(void* arg){ ThreadData* data = static_cast<ThreadData*>(arg); data->setTid(::syscall(SYS_gettid)); data->run(); return (void*)0; }
void __cdecl CMsnProto::MSNServerThread(void* arg) { ThreadData* info = (ThreadData*)arg; if (info->mIsMainThread) isConnectSuccess = false; int tPortNumber = -1; { char* tPortDelim = strrchr(info->mServer, ':'); if (tPortDelim != NULL) { *tPortDelim = '\0'; if ((tPortNumber = atoi(tPortDelim + 1)) == 0) tPortNumber = -1; else if (usingGateway && !(tPortNumber == 80 || tPortNumber == 443)) usingGateway = false; } } if (usingGateway) { if (info->mServer[0] == 0) mir_strcpy(info->mServer, MSN_DEFAULT_LOGIN_SERVER); else if (info->mIsMainThread) mir_strcpy(info->mGatewayIP, info->mServer); if (info->gatewayType) mir_strcpy(info->mGatewayIP, info->mServer); else { if (info->mGatewayIP[0] == 0 && db_get_static(NULL, m_szModuleName, "GatewayServer", info->mGatewayIP, sizeof(info->mGatewayIP))) mir_strcpy(info->mGatewayIP, MSN_DEFAULT_GATEWAY); } } else { if (info->mServer[0] == 0 && db_get_static(NULL, m_szModuleName, "DirectServer", info->mServer, sizeof(info->mServer))) mir_strcpy(info->mServer, MSN_DEFAULT_LOGIN_SERVER); } NETLIBOPENCONNECTION tConn = { 0 }; tConn.cbSize = sizeof(tConn); tConn.flags = NLOCF_V2; tConn.timeout = 5; if (usingGateway) { tConn.flags |= NLOCF_HTTPGATEWAY; tConn.szHost = info->mGatewayIP; tConn.wPort = MSN_DEFAULT_GATEWAY_PORT; } else { tConn.flags = NLOCF_SSL; tConn.szHost = info->mServer; tConn.wPort = MSN_DEFAULT_PORT; } if (tPortNumber != -1) tConn.wPort = (WORD)tPortNumber; debugLogA("Thread started: server='%s:%d', type=%d", tConn.szHost, tConn.wPort, info->mType); info->s = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNetlibUser, (LPARAM)&tConn); if (info->s == NULL) { debugLogA("Connection Failed (%d) server='%s:%d'", WSAGetLastError(), tConn.szHost, tConn.wPort); switch (info->mType) { case SERVER_NOTIFICATION: goto LBL_Exit; break; case SERVER_SWITCHBOARD: if (info->mCaller) msnNsThread->sendPacket("XFR", "SB"); break; } return; } if (usingGateway) CallService(MS_NETLIB_SETPOLLINGTIMEOUT, WPARAM(info->s), info->mGatewayTimeout); debugLogA("Connected with handle=%08X", info->s); if (info->mType == SERVER_NOTIFICATION) info->sendPacketPayload("CNT", "CON", "<connect>%s%s%s<ver>2</ver><agent><os>winnt</os><osVer>5.2</osVer><proc>x86</proc><lcid>en-us</lcid></agent></connect>\r\n", *info->mState?"<xfr><state>":"", *info->mState?info->mState:"", *info->mState?"</state></xfr>":""); else if (info->mType == SERVER_SWITCHBOARD) { info->sendPacket(info->mCaller ? "USR" : "ANS", "%s;%s %s", MyOptions.szEmail, MyOptions.szMachineGuid, info->mCookie); } else if (info->mType == SERVER_FILETRANS && info->mCaller == 0) { info->send("VER MSNFTP\r\n", 12); } if (info->mIsMainThread) { msnNsThread = info; } debugLogA("Entering main recv loop"); info->mBytesInData = 0; for (;;) { int recvResult = info->recv(info->mData + info->mBytesInData, info->mDataSize - info->mBytesInData); if (recvResult == SOCKET_ERROR) { debugLogA("Connection %08p [%08X] was abortively closed", info->s, GetCurrentThreadId()); break; } if (!recvResult) { debugLogA("Connection %08p [%08X] was gracefully closed", info->s, GetCurrentThreadId()); break; } info->mBytesInData += recvResult; #ifdef OBSOLETE if (info->mCaller == 1 && info->mType == SERVER_FILETRANS) { if (MSN_HandleMSNFTP(info, info->mData)) break; } else #endif { for (;;) { char* peol = strchr(info->mData, '\r'); if (peol == NULL) break; int msgLen = (int)(peol - info->mData); if (info->mBytesInData < msgLen + 2) break; //wait for full line end char msg[1024]; strncpy_s(msg, info->mData, msgLen); if (*++peol != '\n') debugLogA("Dodgy line ending to command: ignoring"); else peol++; info->mBytesInData -= peol - info->mData; memmove(info->mData, peol, info->mBytesInData); debugLogA("RECV: %s", msg); if (!isalnum(msg[0]) || !isalnum(msg[1]) || !isalnum(msg[2]) || (msg[3] && msg[3] != ' ')) { debugLogA("Invalid command name"); continue; } if (info->mType != SERVER_FILETRANS) { int handlerResult; if (isdigit(msg[0]) && isdigit(msg[1]) && isdigit(msg[2])) //all error messages handlerResult = MSN_HandleErrors(info, msg); else handlerResult = MSN_HandleCommands(info, msg); if (handlerResult) { if (info->sessionClosed) goto LBL_Exit; info->sendTerminate(); } } #ifdef OBSOLETE else if (MSN_HandleMSNFTP(info, msg)) goto LBL_Exit; #endif } } if (info->mBytesInData == info->mDataSize) { if (!ReallocInfoBuffer(info, info->mDataSize*2)) { debugLogA("sizeof(data) is too small: the longest line won't fit"); break; } } } LBL_Exit: if (info->mIsMainThread) { /* if (!isConnectSuccess && !usingGateway && m_iDesiredStatus != ID_STATUS_OFFLINE) { msnNsThread = NULL; usingGateway = true; ThreadData* newThread = new ThreadData; newThread->mType = SERVER_NOTIFICATION; newThread->mIsMainThread = true; newThread->startThread(&CMsnProto::MSNServerThread, this); } else*/ { if (hKeepAliveThreadEvt) { msnPingTimeout *= -1; SetEvent(hKeepAliveThreadEvt); } if (info->s == NULL) ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NONETWORK); else { #ifdef OBSOLETE p2p_cancelAllSessions(); #endif MSN_CloseConnections(); } if (hHttpsConnection) { Netlib_CloseHandle(hHttpsConnection); hHttpsConnection = NULL; } MSN_GoOffline(); msnNsThread = NULL; } } debugLogA("Thread [%08X] ending now", GetCurrentThreadId()); }
MobileMessageThread::MobileMessageThread(const ThreadData& aData) : mData(aData) { MOZ_ASSERT(aData.participants().Length()); }
TEST(Thread, SetErrorNull) { ThreadData* data = GetThreadData(); data->SetError("Hello"); data->SetError(NULL); EXPECT_STREQ("", data->GetError()); }
int ThreadEntry(void* data) { ThreadData* thread = (ThreadData*)data; thread->Func(); return 0; }
Receiver::ReceiverState Receiver::waitForFinishOrNewCheckpoint( ThreadData &data) { VLOG(1) << data << " entered WAIT_FOR_FINISH_OR_NEW_CHECKPOINT state "; auto &threadStats = data.threadStats_; auto &senderReadTimeout = data.senderReadTimeout_; auto &checkpointIndex = data.checkpointIndex_; auto &newCheckpoints = data.newCheckpoints_; char *buf = data.getBuf(); auto &socket = data.socket_; // should only be called if there are no errors WDT_CHECK(threadStats.getErrorCode() == OK); std::unique_lock<std::mutex> lock(mutex_); // we have to check for checkpoints before checking to see if session ended or // not. because if some checkpoints have not been sent back to the sender, // session should not end newCheckpoints = getNewCheckpoints(checkpointIndex); if (!newCheckpoints.empty()) { return SEND_GLOBAL_CHECKPOINTS; } waitingThreadCount_++; if (areAllThreadsFinished(false)) { endCurGlobalSession(); endCurThreadSession(data); return SEND_DONE_CMD; } // we must send periodic wait cmd to keep the sender thread alive while (true) { WDT_CHECK(senderReadTimeout > 0); // must have received settings int timeoutMillis = senderReadTimeout / kWaitTimeoutFactor; auto waitingTime = std::chrono::milliseconds(timeoutMillis); START_PERF_TIMER conditionAllFinished_.wait_for(lock, waitingTime); RECORD_PERF_RESULT(PerfStatReport::RECEIVER_WAIT_SLEEP) // check if transfer finished or not if (hasCurSessionFinished(data)) { endCurThreadSession(data); return SEND_DONE_CMD; } // check to see if any new checkpoints were added newCheckpoints = getNewCheckpoints(checkpointIndex); if (!newCheckpoints.empty()) { waitingThreadCount_--; return SEND_GLOBAL_CHECKPOINTS; } // must unlock because socket write could block for long time, as long as // the write timeout, which is 5sec by default lock.unlock(); // send WAIT cmd to keep sender thread alive buf[0] = Protocol::WAIT_CMD; if (socket.write(buf, 1) != 1) { PLOG(ERROR) << data << " unable to write WAIT "; threadStats.setErrorCode(SOCKET_WRITE_ERROR); lock.lock(); // we again have to check if the session has finished or not. while // writing WAIT cmd, some other thread could have ended the session, so // going back to ACCEPT_WITH_TIMEOUT state would be wrong if (!hasCurSessionFinished(data)) { waitingThreadCount_--; return ACCEPT_WITH_TIMEOUT; } endCurThreadSession(data); return END; } threadStats.addHeaderBytes(1); lock.lock(); } }
TEST(Thread, GetErrorEmpty) { ThreadData* data = GetThreadData(); const char* error = data->GetError(); EXPECT_TRUE(error); EXPECT_STREQ("", error); }
DWORD WINAPI ThreadCallback(LPVOID data) { ThreadData* threadData = reinterpret_cast<ThreadData*>(data); threadData->ExecuteAllActions(); return 0; }
Receiver::ReceiverState Receiver::sendFileChunks(ThreadData &data) { LOG(INFO) << data << " entered SEND_FILE_CHUNKS state "; char *buf = data.getBuf(); auto bufferSize = data.bufferSize_; auto &socket = data.socket_; auto &threadStats = data.threadStats_; auto &senderReadTimeout = data.senderReadTimeout_; int64_t toWrite; int64_t written; std::unique_lock<std::mutex> lock(mutex_); while (true) { switch (sendChunksStatus_) { case SENT: { lock.unlock(); buf[0] = Protocol::ACK_CMD; toWrite = 1; written = socket.write(buf, toWrite); if (written != toWrite) { LOG(ERROR) << "Socket write error " << toWrite << " " << written; threadStats.setErrorCode(SOCKET_READ_ERROR); return ACCEPT_WITH_TIMEOUT; } threadStats.addHeaderBytes(toWrite); return READ_NEXT_CMD; } case IN_PROGRESS: { lock.unlock(); buf[0] = Protocol::WAIT_CMD; toWrite = 1; written = socket.write(buf, toWrite); if (written != toWrite) { LOG(ERROR) << "Socket write error " << toWrite << " " << written; threadStats.setErrorCode(SOCKET_READ_ERROR); return ACCEPT_WITH_TIMEOUT; } threadStats.addHeaderBytes(toWrite); WDT_CHECK(senderReadTimeout > 0); // must have received settings int timeoutMillis = senderReadTimeout / kWaitTimeoutFactor; auto waitingTime = std::chrono::milliseconds(timeoutMillis); lock.lock(); conditionFileChunksSent_.wait_for(lock, waitingTime); continue; } case NOT_STARTED: { // This thread has to send file chunks sendChunksStatus_ = IN_PROGRESS; lock.unlock(); auto guard = folly::makeGuard([&] { lock.lock(); sendChunksStatus_ = NOT_STARTED; conditionFileChunksSent_.notify_one(); }); const auto &parsedFileChunksInfo = transferLogManager_.getParsedFileChunksInfo(); int64_t off = 0; buf[off++] = Protocol::CHUNKS_CMD; const int64_t numParsedChunksInfo = parsedFileChunksInfo.size(); Protocol::encodeChunksCmd(buf, off, bufferSize, numParsedChunksInfo); written = socket.write(buf, off); if (written > 0) { threadStats.addHeaderBytes(written); } if (written != off) { LOG(ERROR) << "Socket write error " << off << " " << written; threadStats.setErrorCode(SOCKET_READ_ERROR); return ACCEPT_WITH_TIMEOUT; } int64_t numEntriesWritten = 0; // we try to encode as many chunks as possible in the buffer. If a // single // chunk can not fit in the buffer, it is ignored. Format of encoding : // <data-size><chunk1><chunk2>... while (numEntriesWritten < numParsedChunksInfo) { off = sizeof(int32_t); int64_t numEntriesEncoded = Protocol::encodeFileChunksInfoList( buf, off, bufferSize, numEntriesWritten, parsedFileChunksInfo); int32_t dataSize = folly::Endian::little(off - sizeof(int32_t)); folly::storeUnaligned<int32_t>(buf, dataSize); written = socket.write(buf, off); if (written > 0) { threadStats.addHeaderBytes(written); } if (written != off) { break; } numEntriesWritten += numEntriesEncoded; } if (numEntriesWritten != numParsedChunksInfo) { LOG(ERROR) << "Could not write all the file chunks " << numParsedChunksInfo << " " << numEntriesWritten; threadStats.setErrorCode(SOCKET_WRITE_ERROR); return ACCEPT_WITH_TIMEOUT; } // try to read ack int64_t toRead = 1; int64_t numRead = socket.read(buf, toRead); if (numRead != toRead) { LOG(ERROR) << "Socket read error " << toRead << " " << numRead; threadStats.setErrorCode(SOCKET_READ_ERROR); return ACCEPT_WITH_TIMEOUT; } guard.dismiss(); lock.lock(); sendChunksStatus_ = SENT; // sender is aware of previous transferred chunks. logging can now be // enabled transferLogManager_.enableLogging(); transferLogManager_.addLogHeader(); conditionFileChunksSent_.notify_all(); return READ_NEXT_CMD; } } } }
// MsnSendMessage - sends the message to a server int __cdecl CMsnProto::SendMsg(MCONTACT hContact, int flags, const char* pszSrc) { const char *errMsg = NULL; if (!msnLoggedIn) { errMsg = Translate("Protocol is offline"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, 999999, errMsg, this)); return 999999; } char tEmail[MSN_MAX_EMAIL_LEN]; if (MSN_IsMeByContact(hContact, tEmail)) { errMsg = Translate("You cannot send message to yourself"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, 999999, errMsg, this)); return 999999; } char *msg = (char*)pszSrc; if (msg == NULL) return 0; int rtlFlag = (flags & PREF_RTL) ? MSG_RTL : 0; int seq = 0; int netId = Lists_GetNetId(tEmail); switch (netId) { case NETID_MOB: if (mir_strlen(msg) > 133) { errMsg = Translate("Message is too long: SMS page limited to 133 UTF8 chars"); seq = 999997; } else { errMsg = NULL; seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag); } ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); break; case NETID_YAHOO: if (mir_strlen(msg) > 1202) { seq = 999996; errMsg = Translate("Message is too long: MSN messages are limited by 1202 UTF8 chars"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } else { seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } break; default: if (mir_strlen(msg) > 1202) { seq = 999996; errMsg = Translate("Message is too long: MSN messages are limited by 1202 UTF8 chars"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } else { #ifdef OBSOLETE const char msgType = MyOptions.SlowSend ? 'A' : 'N'; bool isOffline; ThreadData *thread = MSN_StartSB(tEmail, isOffline); #else /* MSNP24 doesn't have a switchboard anymore */ bool isOffline = true; ThreadData *thread = NULL; #endif if (thread == NULL) { if (isOffline) { if (netId != NETID_LCS) { seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag | MSG_OFFLINE); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } else { seq = 999993; errMsg = Translate("Offline messaging is not allowed for LCS contacts"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } } #ifdef OBSOLETE else seq = MsgQueue_Add(tEmail, msgType, msg, 0, 0, rtlFlag); } else { seq = thread->sendMessage(msgType, tEmail, netId, msg, rtlFlag); if (!MyOptions.SlowSend) ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); #endif } } break; } return seq; }
CpuCustomManyParticleForce::AngleTermInfo::AngleTermInfo(const string& name, const vector<int>& atoms, const Lepton::CompiledExpression& forceExpression, ThreadData& data) : name(name), p1(atoms[0]), p2(atoms[1]), p3(atoms[2]), forceExpression(forceExpression) { variableIndex = data.expressionSet.getVariableIndex(name); data.requestDeltaPair(p1, p2,delta1, delta1Sign, true); data.requestDeltaPair(p3, p2, delta2, delta2Sign, true); }
static DWORD __stdcall begin_thread(void* arg) { ThreadData* data = (ThreadData*) arg; data->ret = data->func(data->arg); return 0; }
void* GeneticAlgorithmProfile1::Algorithm( void* arg ) { srand (static_cast <unsigned> (time(0))); ThreadData* td = (ThreadData*)arg; if( td->first && td->generation.size() == 0 ) { td->generation = GeneticAlgorithmProfile1::GeneratePopulation(MaxChromosomesPopulationSize, 0, 0); } td->SetSimulating(false); td->SetGaInitialized(true); td->SetGaEnabled(true); if( td->first && td->generation.size() > 0 ) { for(int i = 0; i < td->generation.size(); i++) { GeneticAlgorithmProfile1::CalculateFitness(td, td->generation.at(i)); } std::sort (td->generation.begin(), td->generation.end(), [](Chromosome * a, Chromosome * b) { if (b->fitnessScore == a->fitnessScore) { return b->fitnessHPPercentage < a->fitnessHPPercentage; } return b->fitnessScore < a->fitnessScore; }); td->first = false; } //DBG - LOG std::cout << "\n\n LOG - Generation : INITIAL POP " << " START "; for(int k = 0; k < td->generation.size(); k++) { std::cout << "\n Chromosome : " << k << " fitness score : " << td->generation.at(k)->fitnessScore; } std::cout << "\n ---END--- "; for(int i = 0; i < MaxGenerations; i++) { std::cout << "\n START OF NEW GENERATION\n"; td->previouslyPlayedFitness = td->generation.at(0)->fitnessScore; Chromosome* elite =(Chromosome*) malloc(sizeof(Chromosome)); for ( int j = 0; j < CreepsPerRound; j ++) { elite->healthPoints[j] = td->generation.at(0)->healthPoints[j]; elite->movementSpeed[j] = td->generation.at(0)->movementSpeed[j]; elite->elementalAffinity[j] = td->generation.at(0)->elementalAffinity[j]; elite->fitnessScore = td->generation.at(0)->fitnessScore; } Chromosome* parent1; Chromosome* parent2; if(td->crossoverRate == 100) { int totalFitness = 0; std::vector<double> result(td->generation.size()); for(int x = 0; x < td->generation.size(); x++) { totalFitness = totalFitness + td->generation.at(x)->fitnessScore; } for(int p = 0; p < td->generation.size(); p++) { result[p] = (((double)td->generation.at(p)->fitnessScore) / ((double)totalFitness)) * 100; } bool firstSelected = false; bool secondSelected = false; for(int l = 0 ; l < result.size() ; l++) { float roll = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/100.0f)); if( roll <= result.at(l) ) { if(!firstSelected) { parent1 = td->generation.at(l); firstSelected = true; } else if(!secondSelected) { parent2 = td->generation.at(l); secondSelected = true; } } if(firstSelected && secondSelected) { break; } else { if( l == result.size()-1 ) { l = 0; } } } GeneticAlgorithmProfile1::Crossover(td, parent1, parent2); } td->generation.pop_back(); GeneticAlgorithmProfile1::Mutate(td, &td->generation); td->generation.push_back(elite); for(int k = 0; k < td->generation.size(); k++) { Chromosome* c = td->generation.at(k); GeneticAlgorithmProfile1::CalculateFitness(td, c); } std::sort (td->generation.begin(), td->generation.end(), [](Chromosome * a, Chromosome * b) { if (b->fitnessScore == a->fitnessScore) { return b->fitnessHPPercentage < a->fitnessHPPercentage; } return b->fitnessScore < a->fitnessScore; }); //DBG - LOG std::cout << "\n\n LOG - Generation : " << i << " START "; for(int k = 0; k < td->generation.size(); k++) { std::cout << "\n Chromosome : " << k << " fitness score : " << td->generation.at(k)->fitnessScore; } std::cout << "\n ---END--- "; std::cout << "\n\n GENS PAST " << i; if ( td->generation.at(0)->fitnessScore == MinAcceptableFitness ) { break; } } std::cout << " \n DEPLOYMENT SETTING --- FITNESS : " << td->generation.at(0)->fitnessScore; GeneticAlgorithmProfile1::SetWaveForDeployment(td, td->generation.at(0)); td->SetGaInitialized(false); td->SetGaEnabled(false); td->SetNonGARounds(0); return 0; }
/***PROCESS_SETTINGS_CMD***/ Receiver::ReceiverState Receiver::processSettingsCmd(ThreadData &data) { VLOG(1) << data << " entered PROCESS_SETTINGS_CMD state "; char *buf = data.getBuf(); auto &off = data.off_; auto &oldOffset = data.oldOffset_; auto &numRead = data.numRead_; auto &senderReadTimeout = data.senderReadTimeout_; auto &senderWriteTimeout = data.senderWriteTimeout_; auto &threadStats = data.threadStats_; auto &enableChecksum = data.enableChecksum_; auto &threadProtocolVersion = data.threadProtocolVersion_; Settings settings; int senderProtocolVersion; bool success = Protocol::decodeVersion( buf, off, oldOffset + Protocol::kMaxVersion, senderProtocolVersion); if (!success) { LOG(ERROR) << "Unable to decode version " << data.threadIndex_; threadStats.setErrorCode(PROTOCOL_ERROR); return WAIT_FOR_FINISH_WITH_THREAD_ERROR; } if (senderProtocolVersion != threadProtocolVersion) { LOG(ERROR) << "Receiver and sender protocol version mismatch " << senderProtocolVersion << " " << threadProtocolVersion; int negotiatedProtocol = Protocol::negotiateProtocol(senderProtocolVersion, threadProtocolVersion); if (negotiatedProtocol == 0) { LOG(WARNING) << "Can not support sender with version " << senderProtocolVersion << ", aborting!"; threadStats.setErrorCode(VERSION_INCOMPATIBLE); return SEND_ABORT_CMD; } else { LOG_IF(INFO, threadProtocolVersion != negotiatedProtocol) << "Changing receiver protocol version to " << negotiatedProtocol; threadProtocolVersion = negotiatedProtocol; if (negotiatedProtocol != senderProtocolVersion) { threadStats.setErrorCode(VERSION_MISMATCH); return SEND_ABORT_CMD; } } } success = Protocol::decodeSettings( threadProtocolVersion, buf, off, oldOffset + Protocol::kMaxVersion + Protocol::kMaxSettings, settings); if (!success) { LOG(ERROR) << "Unable to decode settings cmd " << data.threadIndex_; threadStats.setErrorCode(PROTOCOL_ERROR); return WAIT_FOR_FINISH_WITH_THREAD_ERROR; } auto senderId = settings.transferId; if (transferId_ != senderId) { LOG(ERROR) << "Receiver and sender id mismatch " << senderId << " " << transferId_; threadStats.setErrorCode(ID_MISMATCH); return SEND_ABORT_CMD; } senderReadTimeout = settings.readTimeoutMillis; senderWriteTimeout = settings.writeTimeoutMillis; enableChecksum = settings.enableChecksum; if (settings.sendFileChunks) { // We only move to SEND_FILE_CHUNKS state, if download resumption is enabled // in the sender side numRead = off = 0; return SEND_FILE_CHUNKS; } auto msgLen = off - oldOffset; numRead -= msgLen; return READ_NEXT_CMD; }
int CMsnProto::MSN_GCEventHook(WPARAM, LPARAM lParam) { GCHOOK *gch = (GCHOOK*) lParam; if (!gch) return 1; if (_stricmp(gch->pDest->pszModule, m_szModuleName)) return 0; switch (gch->pDest->iType) { case GC_SESSION_TERMINATE: { ThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID); if (thread != NULL) thread->sendTerminate(); break; } case GC_USER_MESSAGE: if (gch->ptszText && gch->ptszText[0]) { ThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID); if (thread) { rtrim(gch->ptszText); // remove the ending linebreak TCHAR* pszMsg = UnEscapeChatTags(NEWTSTR_ALLOCA(gch->ptszText)); thread->sendMessage('N', NULL, NETID_MSN, UTF8(pszMsg), 0); DBVARIANT dbv; int bError = getTString("Nick", &dbv); GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_MESSAGE }; gcd.ptszID = gch->pDest->ptszID; GCEVENT gce = {0}; gce.cbSize = sizeof(GCEVENT); gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; gce.pDest = &gcd; gce.ptszNick = bError ? _T("") : dbv.ptszVal; gce.ptszUID = mir_a2t(MyOptions.szEmail); gce.time = time(NULL); gce.ptszText = gch->ptszText; gce.bIsMe = TRUE; CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); mir_free((void*)gce.ptszUID); if (!bError) MSN_FreeVariant(&dbv); } } break; case GC_USER_CHANMGR: DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat, LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this))); break; case GC_USER_PRIVMESS: { char *email = mir_t2a(gch->ptszUID); HANDLE hContact = MSN_HContactFromEmail(email); MSN_CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); mir_free(email); break; } case GC_USER_LOGMENU: switch(gch->dwData) { case 10: DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat, LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this))); break; case 20: MSN_KillChatSession(gch->pDest->ptszID); break; } break; case GC_USER_NICKLISTMENU: { char *email = mir_t2a(gch->ptszUID); HANDLE hContact = MSN_HContactFromEmail(email); mir_free(email); switch(gch->dwData) { case 10: MSN_CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); break; case 20: MSN_CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0); break; case 110: MSN_KillChatSession(gch->pDest->ptszID); break; } break; } /* haven't implemented in chat.dll case GC_USER_TYPNOTIFY: { int chatID = atoi(p); ThreadData* thread = MSN_GetThreadByContact((HANDLE)-chatID); for (int j=0; j < thread->mJoinedCount; j++) { if ((long)thread->mJoinedContacts[j] > 0) CallService(MS_PROTO_SELFISTYPING, (WPARAM) thread->mJoinedContacts[j], (LPARAM) PROTOTYPE_SELFTYPING_ON); } break; } */ } return 0; }
/***PROCESS_FILE_CMD***/ Receiver::ReceiverState Receiver::processFileCmd(ThreadData &data) { VLOG(1) << data << " entered PROCESS_FILE_CMD state "; const auto &options = WdtOptions::get(); auto &socket = data.socket_; auto &threadIndex = data.threadIndex_; auto &threadStats = data.threadStats_; char *buf = data.getBuf(); auto &numRead = data.numRead_; auto &off = data.off_; auto &oldOffset = data.oldOffset_; auto bufferSize = data.bufferSize_; auto &checkpointIndex = data.checkpointIndex_; auto &pendingCheckpointIndex = data.pendingCheckpointIndex_; auto &enableChecksum = data.enableChecksum_; auto &protocolVersion = data.threadProtocolVersion_; BlockDetails blockDetails; auto guard = folly::makeGuard([&socket, &threadStats] { if (threadStats.getErrorCode() != OK) { threadStats.incrFailedAttempts(); } }); ErrorCode transferStatus = (ErrorCode)buf[off++]; if (transferStatus != OK) { // TODO: use this status information to implement fail fast mode VLOG(1) << "sender entered into error state " << errorCodeToStr(transferStatus); } int16_t headerLen = folly::loadUnaligned<int16_t>(buf + off); headerLen = folly::Endian::little(headerLen); VLOG(2) << "Processing FILE_CMD, header len " << headerLen; if (headerLen > numRead) { int64_t end = oldOffset + numRead; numRead = readAtLeast(socket, buf + end, bufferSize - end, headerLen, numRead); } if (numRead < headerLen) { LOG(ERROR) << "Unable to read full header " << headerLen << " " << numRead; threadStats.setErrorCode(SOCKET_READ_ERROR); return ACCEPT_WITH_TIMEOUT; } off += sizeof(int16_t); bool success = Protocol::decodeHeader(protocolVersion, buf, off, numRead + oldOffset, blockDetails); int64_t headerBytes = off - oldOffset; // transferred header length must match decoded header length WDT_CHECK(headerLen == headerBytes); threadStats.addHeaderBytes(headerBytes); if (!success) { LOG(ERROR) << "Error decoding at" << " ooff:" << oldOffset << " off: " << off << " numRead: " << numRead; threadStats.setErrorCode(PROTOCOL_ERROR); return WAIT_FOR_FINISH_WITH_THREAD_ERROR; } // received a well formed file cmd, apply the pending checkpoint update checkpointIndex = pendingCheckpointIndex; VLOG(1) << "Read id:" << blockDetails.fileName << " size:" << blockDetails.dataSize << " ooff:" << oldOffset << " off: " << off << " numRead: " << numRead; FileWriter writer(threadIndex, &blockDetails, fileCreator_.get()); if (writer.open() != OK) { threadStats.setErrorCode(FILE_WRITE_ERROR); return SEND_ABORT_CMD; } int32_t checksum = 0; int64_t remainingData = numRead + oldOffset - off; int64_t toWrite = remainingData; WDT_CHECK(remainingData >= 0); if (remainingData >= blockDetails.dataSize) { toWrite = blockDetails.dataSize; } threadStats.addDataBytes(toWrite); if (enableChecksum) { checksum = folly::crc32c((const uint8_t *)(buf + off), toWrite, checksum); } if (throttler_) { // We might be reading more than we require for this file but // throttling should make sense for any additional bytes received // on the network throttler_->limit(toWrite + headerBytes); } ErrorCode code = writer.write(buf + off, toWrite); if (code != OK) { threadStats.setErrorCode(code); return SEND_ABORT_CMD; } off += toWrite; remainingData -= toWrite; // also means no leftOver so it's ok we use buf from start while (writer.getTotalWritten() < blockDetails.dataSize) { if (getCurAbortCode() != OK) { LOG(ERROR) << "Thread marked for abort while processing a file." << " port : " << socket.getPort(); return FAILED; } int64_t nres = readAtMost(socket, buf, bufferSize, blockDetails.dataSize - writer.getTotalWritten()); if (nres <= 0) { break; } if (throttler_) { // We only know how much we have read after we are done calling // readAtMost. Call throttler with the bytes read off the wire. throttler_->limit(nres); } threadStats.addDataBytes(nres); if (enableChecksum) { checksum = folly::crc32c((const uint8_t *)buf, nres, checksum); } code = writer.write(buf, nres); if (code != OK) { threadStats.setErrorCode(code); return SEND_ABORT_CMD; } } if (writer.getTotalWritten() != blockDetails.dataSize) { // This can only happen if there are transmission errors // Write errors to disk are already taken care of above LOG(ERROR) << "could not read entire content for " << blockDetails.fileName << " port " << socket.getPort(); threadStats.setErrorCode(SOCKET_READ_ERROR); return ACCEPT_WITH_TIMEOUT; } VLOG(2) << "completed " << blockDetails.fileName << " off: " << off << " numRead: " << numRead; // Transfer of the file is complete here, mark the bytes effective WDT_CHECK(remainingData >= 0) << "Negative remainingData " << remainingData; if (remainingData > 0) { // if we need to read more anyway, let's move the data numRead = remainingData; if ((remainingData < Protocol::kMaxHeader) && (off > (bufferSize / 2))) { // rare so inneficient is ok VLOG(3) << "copying extra " << remainingData << " leftover bytes @ " << off; memmove(/* dst */ buf, /* from */ buf + off, /* how much */ remainingData); off = 0; } else { // otherwise just continue from the offset VLOG(3) << "Using remaining extra " << remainingData << " leftover bytes starting @ " << off; } } else { numRead = off = 0; } if (enableChecksum) { // have to read footer cmd oldOffset = off; numRead = readAtLeast(socket, buf + off, bufferSize - off, Protocol::kMinBufLength, numRead); if (numRead < Protocol::kMinBufLength) { LOG(ERROR) << "socket read failure " << Protocol::kMinBufLength << " " << numRead; threadStats.setErrorCode(SOCKET_READ_ERROR); return ACCEPT_WITH_TIMEOUT; } Protocol::CMD_MAGIC cmd = (Protocol::CMD_MAGIC)buf[off++]; if (cmd != Protocol::FOOTER_CMD) { LOG(ERROR) << "Expecting footer cmd, but received " << cmd; threadStats.setErrorCode(PROTOCOL_ERROR); return WAIT_FOR_FINISH_WITH_THREAD_ERROR; } int32_t receivedChecksum; bool success = Protocol::decodeFooter( buf, off, oldOffset + Protocol::kMaxFooter, receivedChecksum); if (!success) { LOG(ERROR) << "Unable to decode footer cmd"; threadStats.setErrorCode(PROTOCOL_ERROR); return WAIT_FOR_FINISH_WITH_THREAD_ERROR; } if (checksum != receivedChecksum) { LOG(ERROR) << "Checksum mismatch " << checksum << " " << receivedChecksum << " port " << socket.getPort() << " file " << blockDetails.fileName; threadStats.setErrorCode(CHECKSUM_MISMATCH); return ACCEPT_WITH_TIMEOUT; } int64_t msgLen = off - oldOffset; numRead -= msgLen; } if (options.enable_download_resumption) { transferLogManager_.addBlockWriteEntry( blockDetails.seqId, blockDetails.offset, blockDetails.dataSize); } threadStats.addEffectiveBytes(headerBytes, blockDetails.dataSize); threadStats.incrNumBlocks(); return READ_NEXT_CMD; }
TEST(Thread, SetError) { ThreadData* data = GetThreadData(); data->SetError("Hello"); data->SetError("World"); EXPECT_STREQ("World", data->GetError()); }
void Logger::log(LogLevelType level, const std::string &msg, const StackTrace *stackTrace, bool escape /* = false */, bool escapeMore /* = false */) { if (Logger::AlwaysEscapeLog && Logger::Escape) { escape = true; } assert(!escapeMore || escape); ThreadData *threadData = s_threadData.get(); if (threadData->message != -1 && ++threadData->message > MaxMessagesPerRequest && MaxMessagesPerRequest >= 0) { return; } std::unique_ptr<StackTrace> deleter; if (LogNativeStackTrace && stackTrace == nullptr) { deleter.reset(new StackTrace()); stackTrace = deleter.get(); } if (UseSyslog) { syslog(GetSyslogLevel(level), "%s", msg.c_str()); } if (UseLogFile) { FILE *stdf = GetStandardOut(level); FILE *f; if (UseCronolog) { f = cronOutput.getOutputFile(); if (!f) f = stdf; } else { f = Output ? Output : stdf; } std::string header, sheader; if (LogHeader) { header = GetHeader(); if (LogNativeStackTrace) { sheader = header + "[" + stackTrace->hexEncode(5) + "] "; } else { sheader = header; } } const char *escaped = escape ? EscapeString(msg) : msg.c_str(); const char *ending = escapeMore ? "\\n" : "\n"; int bytes; if (f == stdf && s_stderr_color) { bytes = fprintf(f, "%s%s%s%s%s", s_stderr_color, sheader.c_str(), msg.c_str(), ending, ANSI_COLOR_END); } else { bytes = fprintf(f, "%s%s%s", sheader.c_str(), escaped, ending); } FILE *tf = threadData->log; if (tf) { int threadBytes = fprintf(tf, "%s%s%s", header.c_str(), escaped, ending); fflush(tf); threadData->flusher.recordWriteAndMaybeDropCaches(tf, threadBytes); } if (threadData->hook) { threadData->hook(header.c_str(), msg.c_str(), ending, threadData->hookData); } if (escape) { free((void*)escaped); } fflush(f); if (UseCronolog || (Output && !Logger::IsPipeOutput)) { flusher.recordWriteAndMaybeDropCaches(f, bytes); } } }
int __cdecl CMsnProto::SendMsg(HANDLE hContact, int flags, const char* pszSrc) { const char *errMsg = NULL; if (!msnLoggedIn) { errMsg = MSN_Translate("Protocol is offline"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, 999999, errMsg, this)); return 999999; } char tEmail[MSN_MAX_EMAIL_LEN]; if (MSN_IsMeByContact(hContact, tEmail)) { errMsg = MSN_Translate("You cannot send message to yourself"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, 999999, errMsg, this)); return 999999; } char *msg = (char*)pszSrc; if (msg == NULL) return 0; if (flags & PREF_UNICODE) { char* p = strchr(msg, '\0'); if (p != msg) { while (*(++p) == '\0') {} msg = mir_utf8encodeW((wchar_t*)p); } else msg = mir_strdup(msg); } else msg = (flags & PREF_UTF) ? mir_strdup(msg) : mir_utf8encode(msg); int rtlFlag = (flags & PREF_RTL) ? MSG_RTL : 0; int seq = 0; int netId = Lists_GetNetId(tEmail); switch (netId) { case NETID_MOB: if (strlen(msg) > 133) { errMsg = MSN_Translate("Message is too long: SMS page limited to 133 UTF8 chars"); seq = 999997; } else { errMsg = NULL; seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag); } ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); break; case NETID_YAHOO: if (strlen(msg) > 1202) { seq = 999996; errMsg = MSN_Translate("Message is too long: MSN messages are limited by 1202 UTF8 chars"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } else { seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } break; default: if (strlen(msg) > 1202) { seq = 999996; errMsg = MSN_Translate("Message is too long: MSN messages are limited by 1202 UTF8 chars"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } else { const char msgType = MyOptions.SlowSend ? 'A' : 'N'; bool isOffline; ThreadData* thread = MSN_StartSB(tEmail, isOffline); if (thread == NULL) { if (isOffline) { if (netId != NETID_LCS) { seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag | MSG_OFFLINE); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } else { seq = 999993; errMsg = MSN_Translate("Offline messaging is not allowed for LCS contacts"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } } else seq = MsgQueue_Add(tEmail, msgType, msg, 0, 0, rtlFlag); } else { seq = thread->sendMessage(msgType, tEmail, netId, msg, rtlFlag); if (!MyOptions.SlowSend) ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } } break; } mir_free(msg); return seq; }
std::pair<int, int> Logger::log(LogLevelType level, const std::string &msg, const StackTrace *stackTrace, bool escape /* = false */, bool escapeMore /* = false */) { if (Logger::AlwaysEscapeLog && Logger::Escape) { escape = true; } assertx(!escapeMore || escape); // escape must be enabled to escapeMore std::unique_ptr<StackTrace> deleter; if (LogNativeStackTrace && stackTrace == nullptr) { deleter.reset(new StackTrace()); stackTrace = deleter.get(); } if (UseSyslog) { syslog(GetSyslogLevel(level), "%s", msg.c_str()); } int bytes = 0; if (UseLogFile) { ThreadData *threadData = s_threadData.get(); FILE* tf = threadData->log; FILE* f = output(); std::string header, sheader; if (LogHeader) { header = GetHeader(); if (LogNativeStackTrace) { sheader = header + "[" + stackTrace->hexEncode(5) + "] "; } else { sheader = header; } } const char *escaped = escape ? EscapeString(msg) : msg.c_str(); const char *ending = escapeMore ? "\\n" : "\n"; if (f == m_standardOut && s_stderr_color) { bytes = fprintf(f, "%s%s%s%s%s", s_stderr_color, sheader.c_str(), msg.c_str(), ending, ANSI_COLOR_END); } else { bytes = fprintf(f, "%s%s%s", sheader.c_str(), escaped, ending); } if (tf && tf != f) { int threadBytes = fprintf(tf, "%s%s%s", header.c_str(), escaped, ending); fflush(tf); threadData->flusher.recordWriteAndMaybeDropCaches(tf, threadBytes); } if (threadData->hook) { threadData->hook(header.c_str(), msg.c_str(), ending, threadData->hookData); } if (escape) { free((void*)escaped); } fflush(f); if (UseCronolog || (m_output && !m_isPipeOutput)) { m_flusher.recordWriteAndMaybeDropCaches(f, bytes); } } return std::make_pair(1, bytes); }