void LockManager::run() { deadlock_detector_->start(); const std::uint64_t kMaxTryIncoming = static_cast<std::uint64_t>(FLAGS_max_try_incoming); const std::uint64_t kMaxTryInner = static_cast<std::uint64_t>(FLAGS_max_try_incoming); while (true) { for (std::uint64_t tries = 0; tries < kMaxTryIncoming; ++tries) { if (!incoming_requests_.empty()) { const LockRequest request = incoming_requests_.popOne(); if (request.getRequestType() == RequestType::kReleaseLocks) { CHECK(releaseAllLocks(request.getTransactionId())) << "Unexpected condition occured."; } else if (acquireLock(request.getTransactionId(), request.getResourceId(), request.getAccessMode())) { LOG(INFO) << "Transaction " << std::to_string(request.getTransactionId()) << " is waiting " + request.getResourceId().toString(); inner_pending_requests_.push(request); } else { LOG(INFO) << "Transaction " << std::to_string(request.getTransactionId()) << " acquired " + request.getResourceId().toString(); permitted_requests_.push(request); } } } for (std::uint64_t tries = 0; tries < kMaxTryInner; ++tries) { if (!inner_pending_requests_.empty()) { const LockRequest request = inner_pending_requests_.front(); if (acquireLock(request.getTransactionId(), request.getResourceId(), request.getAccessMode())) { inner_pending_requests_.pop(); permitted_requests_.push(request); } } } // Resolve deadlocks. killVictims(); } }
//============================================================================ // NTimer::RemoveTimer : Remove a timer. //---------------------------------------------------------------------------- void NTimer::RemoveTimer(NTimerID theTimer) { StLock acquireLock(mLock); NTimerMapIterator theIter; // Remove all timers if (theTimer == kNTimerAll) { for (theIter = mTimers.begin(); theIter != mTimers.end(); theIter++) NTargetTime::TimerDestroy(theIter->first); mTimers.clear(); } // Remove a single timer else { theIter = mTimers.find(theTimer); NN_ASSERT(theIter != mTimers.end()); if (theIter != mTimers.end()) { NTargetTime::TimerDestroy(theIter->first); mTimers.erase(theIter); } } }
int reportWork(const char *stateFileName, int fLock, int finishedBlockID) { FILE *fState; if(acquireLock(fLock) == LOCK_FAIL) return REPORT_FAIL; if((fState = fopen(stateFileName, "r+")) == NULL) { mexPrintf("Unable to read stateFile\n"); fState = NULL; return REPORT_FAIL; } int blockID; int state; int dummy; while (!feof(fState)) { dummy = fscanf(fState,"%d\t%d\n",&blockID, &state); if(blockID == finishedBlockID) break; } int curPos = ftell(fState); fseek(fState, curPos - 2, SEEK_SET); fputs("2\n",fState); fclose(fState); while(releaseLock(fLock) != LOCK_SUCCESS) sleep(1); return REPORT_SUCCESS; }
//============================================================================ // NThreadPool::Resume : Resume the pool. //---------------------------------------------------------------------------- void NThreadPool::Resume(void) { StLock acquireLock(mLock); NThreadTaskListIterator theIter; // Validate our state NN_ASSERT(mIsPaused); // Schedule the tasks // // The threads are blocked until we release the lock, so any sorting // of the task list will be deferred until the first thread can run. for (theIter = mTasksPending.begin(); theIter != mTasksPending.end(); theIter++) ScheduleTask(*theIter); // Update our state mIsPaused = false; mTasksPending.clear(); }
//============================================================================ // NTimer::ResetTimer : Reset a timer. //---------------------------------------------------------------------------- void NTimer::ResetTimer(NTime fireAfter, NTimerID theTimer) { StLock acquireLock(mLock); NTimerMapIterator theIter; // Adjust all timers if (theTimer == kNTimerAll) { for (theIter = mTimers.begin(); theIter != mTimers.end(); theIter++) NTargetTime::TimerReset(theIter->first, fireAfter); } // Adjust a single timer else { theIter = mTimers.find(theTimer); NN_ASSERT(theIter != mTimers.end()); if (theIter != mTimers.end()) NTargetTime::TimerReset(theIter->first, fireAfter); } }
//============================================================================ // NThreadPool::SetThreadLimit : Set the thread limit. //---------------------------------------------------------------------------- void NThreadPool::SetThreadLimit(NIndex theValue) { StLock acquireLock(mLock); // Set our state mThreadLimit = theValue; }
//============================================================================ // NThreadPool::GetThreadLimit : Get the thread limit. //---------------------------------------------------------------------------- NIndex NThreadPool::GetThreadLimit(void) const { StLock acquireLock(mLock); // Get our state return(mThreadLimit); }
/* * Execute the MONITORENTER instruction */ void op_monitorenter() { Ref object = peekRef(); // don't pop in case gc runs Ref lock = getLock(object); if (lock == NULL) { return; } // roll back, gc done popRef(); // can pop now, no turning back pc++; acquireLock(thread, lock, 1); }
//============================================================================ // NMessageServer::GetStatus : Get the status. //---------------------------------------------------------------------------- NMessageServerStatus NMessageServer::GetStatus(void) const { StLock acquireLock(mLock); // Get the status return(mStatus); }
//============================================================================ // NMessageServer::DisconnectClient : Disconnect a client. //---------------------------------------------------------------------------- void NMessageServer::DisconnectClient(NEntityID clientID) { StLock acquireLock(mLock); // Disconnect the client ClientDisconnected(clientID); RemoveClient( clientID); }
/* virtual */ SysStatus ServerFileVirtFSTmp<T>::handleXObjFree(XHandle xhandle) { SysStatusUval rc; (void) ServerFile::handleXObjFree(xhandle); acquireLock(); rc = DREF(obj)->_close(VClnt(xhandle)->userData(), VClnt(xhandle)->token); releaseLock(); return rc; }
/* virtual */ SysStatusUval ServerFileVirtFSTmp<T>::_write(const char *buf, uval len, __XHANDLE xhandle) { SysStatusUval rc; acquireLock(); tassertMsg(len <= maxIOLoad, "len %ld too big for ppc call\n", len); rc = DREF(obj)->_write(buf, len, VClnt(xhandle)->userData(), VClnt(xhandle)->token); releaseLock(); return rc; }
//============================================================================ // NThreadPool::GetPendingTasks : Get the number of pending tasks. //---------------------------------------------------------------------------- NIndex NThreadPool::GetPendingTasks(void) const { StLock acquireLock(mLock); NIndex numTasks; // Get the size numTasks = (NIndex) mTasks.size(); return(numTasks); }
//============================================================================ // NTargetThread::ThreadSetName : Set the current thread name. //---------------------------------------------------------------------------- void NTargetThread::ThreadSetName(const NString &theName) { StLock acquireLock(gThreadNameLock); NThreadID theID; // Get the state we need theID = ThreadGetID(); gThreadNames[theID] = theName; }
//============================================================================ // NThreadPool::AddTask : Add a task to the pool. //---------------------------------------------------------------------------- void NThreadPool::AddTask(NThreadTask *theTask) { StLock acquireLock(mLock); // Add the task if (mIsPaused) mTasksPending.push_back(theTask); else ScheduleTask(theTask); }
//============================================================================ // NThreadPool::CancelTasks : Cancel the outstanding tasks. //---------------------------------------------------------------------------- void NThreadPool::CancelTasks(void) { StLock acquireLock(mLock); NThreadTaskListConstIterator theIter; // Cancel the tasks for (theIter = mTasks.begin(); theIter != mTasks.end(); theIter++) delete *theIter; mTasks.clear(); }
//============================================================================ // NMessageServer::SocketDidOpen : A socket has been opened. //---------------------------------------------------------------------------- void NMessageServer::SocketDidOpen(NSocket *theSocket) { StLock acquireLock(mLock); // Start the server if (theSocket == &mSocket) { NN_ASSERT(mStatus == kNServerStarting); mStatus = kNServerStarted; ServerStarted(); } }
//============================================================================ // NTargetThread::ThreadGetName : Get the current thread name. //---------------------------------------------------------------------------- NString NTargetThread::ThreadGetName(void) { StLock acquireLock(gThreadNameLock); ThreadNameMapConstIterator theIter; NString theName; // Get the name theIter = gThreadNames.find(ThreadGetID()); if (theIter != gThreadNames.end()) theName = theIter->second; return(theName); }
//============================================================================ // NTimer::HasTimer : Do we have a timer? //---------------------------------------------------------------------------- bool NTimer::HasTimer(NTimerID theTimer) const { StLock acquireLock(mLock); bool hasTimer; // Check our state if (theTimer == kNTimerAny) hasTimer = !mTimers.empty(); else hasTimer = (mTimers.find(theTimer) != mTimers.end()); return(hasTimer); }
//============================================================================ // NThreadPool::Pause : Pause the pool. //---------------------------------------------------------------------------- void NThreadPool::Pause(void) { StLock acquireLock(mLock); // Validate our state NN_ASSERT(!mIsPaused); NN_ASSERT(mTasksPending.empty()); // Update our state mIsPaused = true; }
//============================================================================ // NMessageServer::GetPendingWrites : Get the amount of pending write data. //---------------------------------------------------------------------------- NIndex NMessageServer::GetPendingWrites(void) const { StLock acquireLock(mLock); NClientInfoMapConstIterator theIter; NIndex theSize; // Check the sockets theSize = 0; for (theIter = mClients.begin(); theIter != mClients.end(); theIter++) theSize += theIter->second.theSocket->GetPendingWrites(); return(theSize); }
//============================================================================ // NTimer::AddTimer : Add a timer. //---------------------------------------------------------------------------- NTimerID NTimer::AddTimer(const NTimerFunctor &theFunctor, NTime fireAfter, NTime fireEvery) { StLock acquireLock(mLock); NTimerID theID; // Create th etimer theID = NTargetTime::TimerCreate(theFunctor, fireAfter, fireEvery); if (theID != kNTimerNone) { NN_ASSERT(mTimers.find(theID) == mTimers.end()); mTimers[theID] = theFunctor; } return(theID); }
bool ApplicationLaunch::sendMessage(QString filename) { if (acquireLock()) return false; HWND hwndAppLaunch = NULL; do { hwndAppLaunch = ::FindWindowEx(HWND_MESSAGE, hwndAppLaunch, NULL, WINDOW_TITLE); } while (hwndAppLaunch == (HWND)winId()); // Ignore ourselves if (::IsWindow(hwndAppLaunch)) { HWND hwnd = reinterpret_cast<HWND>(::SendMessage(hwndAppLaunch, wmGetMainWindowHandle(), 0, 0)); if (::IsWindow(hwnd)) { HWND hwndPopup = ::GetLastActivePopup(hwnd); if (::IsWindow(hwndPopup)) hwnd = hwndPopup; ::SetForegroundWindow(hwnd); if (::IsIconic(hwnd)) ::ShowWindow(hwnd, SW_RESTORE); if (!filename.isEmpty()) { QByteArray data = filename.toUtf8(); COPYDATASTRUCT copydata; copydata.dwData = OPENFILE; copydata.lpData = data.data(); copydata.cbData = data.size(); HWND sender = (HWND)winId(); ::SendMessage(hwndAppLaunch, WM_COPYDATA, reinterpret_cast<WPARAM>(sender), reinterpret_cast<LPARAM>(©data)); } } } return true; }
/* virtual */ SysStatusUval ServerFileVirtFSTmp<T>::_read(char *buf, uval len, __XHANDLE xhandle) { SysStatus rc; acquireLock(); #ifdef TESTING_ITFC_WITH_OFFSET tassertMsg(len <= maxIOLoad, "len %ld too big for ppc call\n", len); rc = DREF(obj)->_readOff(buf, len, Clnt(xhandle)->filePosition, VClnt(xhandle)->userData(), VClnt(xhandle)->token); _IF_FAILURE_RET(rc); Clnt(xhandle)->filePosition += _SGETUVAL(rc); releaseLock(); return rc; #else passertMsg(Clnt(xhandle)->isSharingOffset == 0, "NIY\n"); rc = DREF(obj)->_getMaxReadSize(bufsize, VClnt(xhandle)->token); if (_FAILURE(rc)) { releaseLock(); return rc; } tassertMsg(bufsize <= maxIOLoad, "bufsize %ld too big for ppc call\n", len); // using read interface where data is returned from beginging of file char *full_buf = (char*) AllocGlobal::alloc(bufsize); rc = DREF(obj)->_read(full_buf, bufsize, VClnt(xhandle)->userData(), VClnt(xhandle)->token); _IF_FAILURE_RET(rc); uval length_read = _SGETUVAL(rc); if (length_read > 0 && Clnt(xhandle)->filePosition < length_read) { uval offset = Clnt(xhandle)->filePosition; if (len > length_read - offset) { len = length_read - offset; } memcpy(buf, &full_buf[offset], len); Clnt(xhandle)->filePosition += len; releaseLock(); return _SRETUVAL(len); } else { releaseLock(); return _SERROR(2160, FileLinux::EndOfFile, 0); } #endif }
//============================================================================ // NMessageServer::Start : Start the server. //---------------------------------------------------------------------------- void NMessageServer::Start(void) { StLock acquireLock(mLock); // Validate our parameters and state NN_ASSERT(mPort != 0); NN_ASSERT(mMaxClients >= 1 && mMaxClients <= kNEntityClientsMax); NN_ASSERT(mStatus == kNServerStopped); // Start the server mStatus = kNServerStarting; mSocket.Open(mPort); }
//============================================================================ // NMessageServer::SocketHasConnection : The socket has a connection. //---------------------------------------------------------------------------- NSocketConnectionFunctor NMessageServer::SocketHasConnection(NSocket *theSocket, NSocket *newSocket) { StLock acquireLock(mLock); NSocketConnectionFunctor theFunctor; // Validate our parameters and state NN_ASSERT(theSocket == &mSocket); NN_UNUSED(theSocket); // Get the functor if (mStatus == kNServerStarted) theFunctor = BindSelf(NMessageServer::ServerThread, newSocket); return(theFunctor); }
void ThreadedScheduler::tick() { //unsigned int num_popped = 0; //bool some_todo = true; //while (some_todo) //{ // Message message; // some_todo = queue_.try_pop(message); // if (some_todo) // { // handlePoppedMessage(message); // } // ++ num_popped; // if (num_popped >= max_messages_per_tick_) // some_todo = false; //} ScopedLock::ptr lock = acquireLock(); tickGraphs(); //std::cout << "ThreadedScheduler" << __FUNCTION__ << std::endl; }
//============================================================================ // NMessageServer::SendMessage : Send a message. //---------------------------------------------------------------------------- void NMessageServer::SendMessage(const NNetworkMessage &theMsg) { StLock acquireLock(mLock); NClientInfoMapConstIterator theIter; NEntityID dstID; // Get the state we need dstID = theMsg.GetDestination(); // Send to self if (dstID == GetID()) ReceivedMessage(theMsg); // Send to everyone else if (dstID == kNEntityEveryone) { ReceivedMessage(theMsg); for (theIter = mClients.begin(); theIter != mClients.end(); theIter++) (void) WriteMessage(theIter->second.theSocket, theMsg, false); } // Send to a client // // To handle tainted data, we check as well as assert. else { theIter = mClients.find(dstID); NN_ASSERT(theIter != mClients.end()); if (theIter != mClients.end()) (void) WriteMessage(theIter->second.theSocket, theMsg, false); } }
/** * The rxapi main entry point. * * @param argc The command line arguments * @param argv The arguments * * @return The completion return code. */ int main(int argc, char *argv[]) { if (argc > 1) { printf("rxapi: no args allowed\n"); } // a buffer for generating the name char lockFileName[PATH_MAX + 100]; // the location of the lock file char pipePath[PATH_MAX]; // determine the best place to put this SysServerLocalSocketConnectionManager::getServiceLocation(pipePath, sizeof(pipePath)); snprintf(lockFileName, sizeof(lockFileName), "%s.lock", pipePath); printf("rxapi: lockfile path is %s\n", lockFileName); // see if we can get the lock file before proceeding. This is one // file per user. int fd; if ((fd = acquireLock(lockFileName)) == -1) { printf("rxapi: lockfile is locked by another rxapi instance; exiting\n"); return EACCES; } printf("rxapi: lockfile lock acquired\n"); struct sigaction sa; // handle kill -15 (void) sigemptyset(&sa.sa_mask); (void) sigaddset(&sa.sa_mask, SIGTERM); sa.sa_flags = SA_RESTART; sa.sa_handler = Stop; if (sigaction(SIGTERM, &sa, NULL) == -1) { printf("rxapi: sigaction(SIGTERM) failed; exiting\n"); exit(1); } // turn off SIGPIPE signals in case the other end of the // pipe terminates on us. signal(SIGPIPE, SIG_IGN); try { // create a connection object that will be the server target SysServerLocalSocketConnectionManager *c = new SysServerLocalSocketConnectionManager(); // try to create the named pipe used for this server. If this fails, we // likely have an instance of the daemon already running, so just fail quietly. const char *service = SysServerLocalSocketConnectionManager::generateServiceName(); printf("rxapi: service path is %s\n", service); if (!c->bind(service)) { printf("rxapi: service is locked by another rxapi instance; exiting\n"); delete c; return EACCES; } apiServer.initServer(c); // start up the server printf("rxapi: service successfully started; listening\n"); apiServer.listenForConnections(); // go into the message loop } catch (ServiceException *e) { delete e; // just ignore errors } apiServer.terminateServer(); // shut everything down releaseLock(lockFileName, fd); // release the exclusive lock printf("rxapi: service stopped and lockfile released; exiting\n"); return 0; }
/* * Execute the specified method. Return true if the method is executed, * false if it is rolled back for garbage collection. * * target: object for instance methods, class for static * method: the method to be run * offset: amount to increment program counter */ int executeMethod(Ref target, Ref method, int offset) { /* printf("["); if (method[ENTRY_FLAGS].i & ACC_STATIC) { debugString(target[TYPE_NAME].s); } else { debugString(method[ENTRY_OWNER].s[TYPE_NAME].s); } printf("."); debugString(method[ENTRY_NAME].s); debugString(method[ENTRY_DESCRIPTOR].s); printf("]\n"); */ // check for native method Int argcount = getInt(method, METHOD_ARG_COUNT); Int flags = getInt(method, ENTRY_FLAGS); if (flags & ACC_NATIVE) { return executeNativeMethod(target, method, offset); } // if synchronized, acquire the lock Ref lock = NULL; if (flags & ACC_SYNCHRONIZED) { lock = getLock(target); if (lock == NULL) { return FALSE; } // rollback, gc done acquireLock(thread, lock, 0); if (thread == NULL) { return FALSE; } // rollback, wait for lock } // allocate space for new frame Int maxLocals = getInt(method, METHOD_MAX_LOCALS); Int maxStack = getInt(method, METHOD_MAX_STACK); int numWords = FRAME_LOCALS + 2*maxLocals + 2*maxStack; Ref newFrame = allocate(numWords, HEADER_STACK_FRAME); if (newFrame == NULL) { return FALSE; } // rollback, gc done // increment lock count now that instruction can't be rolled back if (flags & ACC_SYNCHRONIZED) { Int count = getInt(lock, LOCK_COUNT); setInt(lock, LOCK_COUNT, count + 1); } // initialise new frame int hash = (char*) newFrame - (char*) core; Ref frameType = getRef(frame, OBJECT_TYPE); setInt(newFrame, OBJECT_HASHCODE, hash); setRef(newFrame, OBJECT_LOCK, lock); setRef(newFrame, OBJECT_TYPE, frameType); setRef(newFrame, FRAME_RETURN_FRAME, frame); setRef(newFrame, FRAME_METHOD, method); setInt(newFrame, FRAME_RETURN_PC, pc + offset); setInt(newFrame, FRAME_PC, 0); setInt(newFrame, FRAME_SP, numWords * 4); // pop arguments off current stack and write to new frame int index = argcount; while (--index >= 0) { if (refOnStack()) { setLocalRef(index, popRef(), newFrame); } else { setLocalInt(index, popInt(), newFrame); } } // point current thread to new frame saveRegisters(); setRef(thread, THREAD_FRAME, newFrame); loadRegisters(); return TRUE; }