// static void FieldTrialList::StatesToString(std::string* output) { if(!global_) { return; } DCHECK(output->empty()); AutoLock auto_lock(global_->lock_); for(RegistrationList::iterator it=global_->registered_.begin(); it!=global_->registered_.end(); ++it) { const std::string name = it->first; std::string group_name = it->second->group_name_internal(); if(group_name.empty()) { continue; // Should not include uninitialized trials. } DCHECK_EQ(name.find(kPersistentStringSeparator), std::string::npos); DCHECK_EQ(group_name.find(kPersistentStringSeparator), std::string::npos); output->append(name); output->append(1, kPersistentStringSeparator); output->append(group_name); output->append(1, kPersistentStringSeparator); } }
void Loop::AddService(const string& service_name, Service* service) { AutoLock<Mutex> auto_lock(&service_lock_); Assert(service_map_.find(service_name) == service_map_.end()); service_map_[service_name] = service; }
ConditionVariable::~ConditionVariable() { AutoLock auto_lock(internal_lock_); run_state_ = SHUTDOWN; // Prevent any more waiting. DCHECK_EQ(recycling_list_size_, allocation_counter_); if(recycling_list_size_ != allocation_counter_) { // Rare shutdown problem. // There are threads of execution still in this->TimedWait() and yet the // caller has instigated the destruction of this instance :-/. // A common reason for such "overly hasty" destruction is that the caller // was not willing to wait for all the threads to terminate. Such hasty // actions are a violation of our usage contract, but we'll give the // waiting thread(s) one last chance to exit gracefully (prior to our // destruction). // Note: waiting_list_ *might* be empty, but recycling is still pending. AutoUnlock auto_unlock(internal_lock_); Broadcast(); // Make sure all waiting threads have been signaled. Sleep(10); // Give threads a chance to grab internal_lock_. // All contained threads should be blocked on user_lock_ by now :-). } // Reacquire internal_lock_. DCHECK_EQ(recycling_list_size_, allocation_counter_); }
/// /// set_last_error will attempt to keep the first error reported /// - this will only update the value if an error has not yet been report for this state /// reset_last_error will directly overwrite last_error back for the start of the next state /// /// both of these methods are private, only to be called by ctsSocket and ctsSocketState /// void ctsSocket::set_last_error(DWORD _error) throw() { ctAutoReleaseCriticalSection auto_lock(&this->socket_cs); // update last_error under lock, only if not previously set if (ctsIOPatternStatusIORunning == this->last_error) { this->last_error = _error; } }
Service* Loop::GetService(const string& service) { AutoLock<Mutex> auto_lock(&service_lock_); ServiceMap::iterator it = service_map_.find(service); if (it != service_map_.end()) return it->second; else return NULL; }
// static size_t FieldTrialList::GetFieldTrialCount() { if(!global_) { return 0; } AutoLock auto_lock(global_->lock_); return global_->registered_.size(); }
// static FieldTrial* FieldTrialList::Find(const std::string& name) { if(!global_) { return NULL; } AutoLock auto_lock(global_->lock_); return global_->PreLockedFind(name); }
void ConditionVariable::TimedWait(int millSeconds) { Event* waiting_event; HANDLE handle; { AutoLock auto_lock(internal_lock_); if (RUNNING != run_state_) return; // Destruction in progress. waiting_event = GetEventForWaiting(); handle = waiting_event->handle(); //DCHECK(handle); } // Release internal_lock. { AutoUnlock unlock(user_lock_); // Release caller's lock WaitForSingleObject(handle, static_cast<DWORD>(millSeconds)); // Minimize spurious signal creation window by recycling asap. AutoLock auto_lock(internal_lock_); RecycleEvent(waiting_event); // Release internal_lock_ } // Reacquire callers lock to depth at entry. }
void ctsSocket::set_socket(SOCKET _socket) throw() { ctAutoReleaseCriticalSection auto_lock(&this->socket_cs); ctl::ctFatalCondition( (this->socket != INVALID_SOCKET), L"ctsSocket::set_socket trying to set a SOCKET (%Iu) when it has already been set in this object (%Iu)", _socket, this->socket); this->socket = _socket; }
std::shared_ptr<ctThreadIocp> ctsSocket::thread_pool() { // use the SOCKET cs to also guard creation of this TP object ctAutoReleaseCriticalSection auto_lock(&this->socket_cs); // must verify a valid socket first to avoid racing destrying the iocp shared_ptr as we try to create it here if ((this->socket != INVALID_SOCKET) && (!this->tp_iocp)) { this->tp_iocp = std::make_shared<ctThreadIocp>(this->socket, ctsConfig::Settings->PTPEnvironment); // can throw } return this->tp_iocp; }
// Signal() will select one of the waiting threads, and signal it (signal its // cv_event). For better performance we signal the thread that went to sleep // most recently (LIFO). If we want fairness, then we wake the thread that has // been sleeping the longest (FIFO). void ConditionVariable::Signal() { HANDLE handle; { AutoLock auto_lock(internal_lock_); if (waiting_list_.IsEmpty()) return; // No one to signal. // Only performance option should be used. // This is not a leak from waiting_list. See FAQ-question 12. handle = waiting_list_.PopBack()->handle(); // LIFO. } // Release internal_lock_. SetEvent(handle); }
FieldTrialList::~FieldTrialList() { AutoLock auto_lock(lock_); while(!registered_.empty()) { RegistrationList::iterator it = registered_.begin(); it->second->Release(); registered_.erase(it->first); } DCHECK_EQ(this, global_); global_ = NULL; }
bool CStrHistory::PopEvent(CString* pstrMsg) { CAutoLock auto_lock(&m_Sync); if (m_History.empty()) return false; *pstrMsg = m_History[0]; m_History.erase(m_History.begin()); return true; }
// static void FieldTrialList::Register(FieldTrial* trial) { if(!global_) { used_without_global_ = true; return; } AutoLock auto_lock(global_->lock_); DCHECK(!global_->PreLockedFind(trial->name())); trial->AddRef(); global_->registered_[trial->name()] = trial; }
void CMessageBrokerController::sendJsonMessage(Json::Value& message) { DBG_MSG(("CMessageBrokerController::sendJsonMessage()\n")); sync_primitives::AutoLock auto_lock(queue_lock_); std::string mes = m_writer.write(message); if (!isNotification(message) && !isResponse(message)) {// not notification, not a response, store id and method name to recognize an answer mWaitResponseQueue.insert(std::map<std::string, std::string>::value_type(message["id"].asString(), message["method"].asString())); } int bytesSent = Send(mes); bytesSent = bytesSent; // to prevent compiler warnings in case DBG_MSG off DBG_MSG(("Length:%d, Sent: %d bytes\n", mes.length(), bytesSent)); }
// Start the dispatcher by creating a joinable thread. int Scheduler::start_dispatcher() { Auto_Mutex auto_lock(_lock); if (_dispatcher_thread_running) return -1; _dispatcher_thread_running = true; return Thread::create_joinable(_thread, _thread_proc, this); return 0; }
/// /// SetTimer schedules the callback function to be invoked with the given ctsSocket and ctsIOTask /// - note that the timer /// - can throw under low resource conditions /// void ctsSocket::set_timer(const ctsIOTask& _task, std::function<void(std::weak_ptr<ctsSocket>, const ctsIOTask&)> _func) { ctAutoReleaseCriticalSection auto_lock(&this->socket_cs); if (!this->tp_timer) { this->tp_timer = std::make_shared<ctl::ctThreadpoolTimer>(ctsConfig::Settings->PTPEnvironment); } // register a weak pointer after creating a shared_ptr from the 'this' ptry this->tp_timer->schedule_singleton( _func, std::weak_ptr<ctsSocket>(this->shared_from_this()), _task, _task.time_offset_milliseconds); }
std::string CMessageBrokerController::findMethodById(std::string id) { DBG_MSG(("CMessageBrokerController::findMethodById()\n")); sync_primitives::AutoLock auto_lock(queue_lock_); std::string res = ""; std::map <std::string, std::string>::iterator it; it = mWaitResponseQueue.find(id); if (it != mWaitResponseQueue.end()) { res = (*it).second; mWaitResponseQueue.erase(it); } return res; }
int Scheduler::stop_dispatcher() { Auto_Mutex auto_lock(_lock); if (!_dispatcher_thread_running) return -1; // Setting this to false will cause _thread_proc() to fall out of its // loop and terminate. _dispatcher_thread_running = false; return 0; }
// Broadcast() is guaranteed to signal all threads that were waiting (i.e., had // a cv_event internally allocated for them) before Broadcast() was called. void ConditionVariable::Broadcast() { std::stack<HANDLE> handles; // See FAQ-question-10. { AutoLock auto_lock(internal_lock_); if (waiting_list_.IsEmpty()) return; while (!waiting_list_.IsEmpty()) // This is not a leak from waiting_list_. See FAQ-question 12. handles.push(waiting_list_.PopBack()->handle()); } // Release internal_lock_. while (!handles.empty()) { SetEvent(handles.top()); handles.pop(); } }
void ctsSocket::close_socket() throw() { // not holding the socket lock when trying to call back through the iopattern // - to avoid potential deadlocks auto ref_io_pattern(this->io_pattern); if (ref_io_pattern) { ref_io_pattern->end_pattern(); } ctAutoReleaseCriticalSection auto_lock(&this->socket_cs); if (this->socket != INVALID_SOCKET) { ::closesocket(this->socket); this->socket = INVALID_SOCKET; } }
bool CLog::AddString(__ulong Category, DEBUG_INFO_LEVEL Level, PTCHAR ptchLogString) { bool bClose = false; bool bRet = false; PWCHAR pwchLogStr; DWORD Len; DWORD dwWr; if (m_pParentLog) m_pParentLog->AddFormatedString(Category, Level, _T("%s"), ptchLogString); if ((Category & m_DbgFilterCat) && (Level <= m_DbgFilterLevel)) __DbPrintEx(Category, Level, _T("%s"), ptchLogString); //__DbPrintEx(DCB_SYSTEM, DL_INFO, L"m_FilterCat=%02X m_FilterLevel=%02X", m_FilterCat, m_FilterLevel); if ((Category & m_FilterCat)==0 || (Level > m_FilterLevel)) return true; CAutoLock auto_lock(&m_Sync); if (!IsValid()) { if (!OpenFile()) return false; bClose = true; } pwchLogStr = (PWCHAR) global_Alloc(_WSTR_LEN_B(ptchLogString) + 0x100); if (NULL != pwchLogStr) { CurrentTimeToString(pwchLogStr); lstrcat(pwchLogStr, ptchLogString); lstrcat(pwchLogStr, _T("\r\n")); Len = lstrlen(pwchLogStr); WriteFile(m_hFile, pwchLogStr, Len * sizeof(WCHAR), &dwWr, NULL); FreeStr(pwchLogStr); if (0 != dwWr) bRet = true; } if (bClose) ResetState(); return bRet; }
size_t Scheduler::add_timer(uint64 timeout, Timer_Proc proc, void* arg) { Auto_Mutex auto_lock(_lock); // Create new timer: Timer* timer = new Timer; timer->id = _id_pool.get(); timer->deadline = Time::now() + timeout; timer->proc = proc; timer->arg = arg; // Insert timer into list: _insert_timer(_list, timer); if (_auto_dispatch && !_dispatcher_thread_running) start_dispatcher(); return timer->id; }
bool Scheduler::remove_timer(size_t timer_id) { Auto_Mutex auto_lock(_lock); for (List_Elem* p = _list.head; p; p = p->next) { Timer* timer = (Timer*)p; if (timer->id == timer_id) { // Found! _list.remove(p); _id_pool.put(timer->id); delete timer; if (_auto_dispatch && _list.empty()) stop_dispatcher(); return true; } } // Not found! return false; }
void CStrHistory::PushEvent(CString* pstrMsg) { CAutoLock auto_lock(&m_Sync); m_History.push_back(*pstrMsg); }
void Loop::RemoveService(const string& service) { AutoLock<Mutex> auto_lock(&service_lock_); deletelist_.push_back(service); }
unsigned int ctsSocket::get_last_error() const throw() { ctAutoReleaseCriticalSection auto_lock(&this->socket_cs); return this->last_error; }
void ctsSocket::reset_last_error() throw() { ctAutoReleaseCriticalSection auto_lock(&this->socket_cs); this->last_error = ctsIOPatternStatusIORunning; }