bool VDLoopThrottle::Delay() { float desiredRatio = mThrottleFactor; if (desiredRatio >= 1.0f) return true; if (desiredRatio <= 0.0f) { ::Sleep(100); return false; } uint32 total = mActiveTimeWindowSum + mWaitTimeWindowSum; if (total > 0) { float delta = mActiveTimeWindowSum - total * mThrottleFactor; mWaitTime += delta * (0.1f / 16.0f); } if (mWaitTime > 0) { int delayTime = VDRoundToInt(mWaitTime); if (delayTime > 1000) delayTime = 1000; BeginWait(); ::Sleep(delayTime); EndWait(); } return true; }
NamingServiceThread::Actions::~Actions() { // Remove all sockets from SocketMap for (std::vector<ServerNode>::const_iterator it = _last_servers.begin(); it != _last_servers.end(); ++it) { SocketMapRemove(it->addr); } EndWait(0); }
/* ** Clean up after the execution of a shell command sub-process and present ** the output/errors to the user as requested in the initial issueCommand ** call. If "terminatedOnError" is true, don't bother trying to read the ** output, just close the i/o descriptors, free the memory, and restore the ** user interface state. */ static void finishCmdExecution(WindowInfo *window, int terminatedOnError) { shellCmdInfo *cmdData = window->shellCmdData; textBuffer *buf; int status, failure, errorReport, reselectStart, outTextLen, errTextLen; int resp, cancel = False, fromMacro = cmdData->fromMacro; char *outText, *errText = NULL; /* Cancel any pending i/o on the file descriptors */ if (cmdData->stdoutInputID != 0) XtRemoveInput(cmdData->stdoutInputID); if (cmdData->stdinInputID != 0) XtRemoveInput(cmdData->stdinInputID); if (cmdData->stderrInputID != 0) XtRemoveInput(cmdData->stderrInputID); /* Close any file descriptors remaining open */ close(cmdData->stdoutFD); if (cmdData->flags & ERROR_DIALOGS) close(cmdData->stderrFD); if (cmdData->inPtr != NULL) close(cmdData->stdinFD); /* Free the provided input text */ if (cmdData->input != NULL) XtFree(cmdData->input); /* Cancel pending timeouts */ if (cmdData->flushTimeoutID != 0) XtRemoveTimeOut(cmdData->flushTimeoutID); if (cmdData->bannerTimeoutID != 0) XtRemoveTimeOut(cmdData->bannerTimeoutID); /* Clean up waiting-for-shell-command-to-complete mode */ if (!cmdData->fromMacro) { EndWait(window->shell); SetSensitive(window, window->cancelShellItem, False); if (cmdData->bannerIsUp) ClearModeMessage(window); } /* If the process was killed or became inaccessable, give up */ if (terminatedOnError) { freeBufList(&cmdData->outBufs); freeBufList(&cmdData->errBufs); waitpid(cmdData->childPid, &status, 0); goto cmdDone; } /* Assemble the output from the process' stderr and stdout streams into null terminated strings, and free the buffer lists used to collect it */ outText = coalesceOutput(&cmdData->outBufs, &outTextLen); if (cmdData->flags & ERROR_DIALOGS) errText = coalesceOutput(&cmdData->errBufs, &errTextLen); /* Wait for the child process to complete and get its return status */ waitpid(cmdData->childPid, &status, 0); /* Present error and stderr-information dialogs. If a command returned error output, or if the process' exit status indicated failure, present the information to the user. */ if (cmdData->flags & ERROR_DIALOGS) { failure = WIFEXITED(status) && WEXITSTATUS(status) != 0; errorReport = *errText != '\0'; if (failure && errorReport) { removeTrailingNewlines(errText); truncateString(errText, DF_MAX_MSG_LENGTH); resp = DialogF(DF_WARN, window->shell, 2, "Warning", "%s", "Cancel", "Proceed", errText); cancel = resp == 1; } else if (failure) { truncateString(outText, DF_MAX_MSG_LENGTH-70); resp = DialogF(DF_WARN, window->shell, 2, "Command Failure", "Command reported failed exit status.\n" "Output from command:\n%s", "Cancel", "Proceed", outText); cancel = resp == 1; } else if (errorReport) { removeTrailingNewlines(errText); truncateString(errText, DF_MAX_MSG_LENGTH); resp = DialogF(DF_INF, window->shell, 2, "Information", "%s", "Proceed", "Cancel", errText); cancel = resp == 2; } XtFree(errText); if (cancel) { XtFree(outText); goto cmdDone; } } /* If output is to a dialog, present the dialog. Otherwise insert the (remaining) output in the text widget as requested, and move the insert point to the end */ if (cmdData->flags & OUTPUT_TO_DIALOG) { removeTrailingNewlines(outText); if (*outText != '\0') createOutputDialog(window->shell, outText); } else if (cmdData->flags & OUTPUT_TO_STRING) { ReturnShellCommandOutput(window,outText, WEXITSTATUS(status)); } else { buf = TextGetBuffer(cmdData->textW); if (!BufSubstituteNullChars(outText, outTextLen, buf)) { fprintf(stderr,"NEdit: Too much binary data in shell cmd output\n"); outText[0] = '\0'; } if (cmdData->flags & REPLACE_SELECTION) { reselectStart = buf->primary.rectangular ? -1 : buf->primary.start; BufReplaceSelected(buf, outText); TextSetCursorPos(cmdData->textW, buf->cursorPosHint); if (reselectStart != -1) BufSelect(buf, reselectStart, reselectStart + strlen(outText)); } else { safeBufReplace(buf, &cmdData->leftPos, &cmdData->rightPos, outText); TextSetCursorPos(cmdData->textW, cmdData->leftPos+strlen(outText)); } } /* If the command requires the file to be reloaded afterward, reload it */ if (cmdData->flags & RELOAD_FILE_AFTER) RevertToSaved(window); /* Command is complete, free data structure and continue macro execution */ XtFree(outText); cmdDone: XtFree((char *)cmdData); window->shellCmdData = NULL; if (fromMacro) ResumeMacroExecution(window); }
void NamingServiceThread::Actions::ResetServers( const std::vector<ServerNode>& servers) { _servers.assign(servers.begin(), servers.end()); // Diff servers with _last_servers by comparing sorted vectors. // Notice that _last_servers is always sorted. std::sort(_servers.begin(), _servers.end()); const size_t dedup_size = std::unique(_servers.begin(), _servers.end()) - _servers.begin(); if (dedup_size != _servers.size()) { LOG(WARNING) << "Removed " << _servers.size() - dedup_size << " duplicated servers"; _servers.resize(dedup_size); } _added.resize(_servers.size()); std::vector<ServerNode>::iterator _added_end = std::set_difference(_servers.begin(), _servers.end(), _last_servers.begin(), _last_servers.end(), _added.begin()); _added.resize(_added_end - _added.begin()); _removed.resize(_last_servers.size()); std::vector<ServerNode>::iterator _removed_end = std::set_difference(_last_servers.begin(), _last_servers.end(), _servers.begin(), _servers.end(), _removed.begin()); _removed.resize(_removed_end - _removed.begin()); _added_sockets.clear(); for (size_t i = 0; i < _added.size(); ++i) { ServerNodeWithId tagged_id; tagged_id.node = _added[i]; CHECK_EQ(SocketMapInsert(_added[i].addr, &tagged_id.id), 0); _added_sockets.push_back(tagged_id); } _removed_sockets.clear(); for (size_t i = 0; i < _removed.size(); ++i) { ServerNodeWithId tagged_id; tagged_id.node = _removed[i]; CHECK_EQ(0, SocketMapFind(_removed[i].addr, &tagged_id.id)); _removed_sockets.push_back(tagged_id); } // Refresh sockets if (_removed_sockets.empty()) { _sockets = _owner->_last_sockets; } else { std::sort(_removed_sockets.begin(), _removed_sockets.end()); _sockets.resize(_owner->_last_sockets.size()); std::vector<ServerNodeWithId>::iterator _sockets_end = std::set_difference( _owner->_last_sockets.begin(), _owner->_last_sockets.end(), _removed_sockets.begin(), _removed_sockets.end(), _sockets.begin()); _sockets.resize(_sockets_end - _sockets.begin()); } if (!_added_sockets.empty()) { const size_t before_added = _sockets.size(); std::sort(_added_sockets.begin(), _added_sockets.end()); _sockets.insert(_sockets.end(), _added_sockets.begin(), _added_sockets.end()); std::inplace_merge(_sockets.begin(), _sockets.begin() + before_added, _sockets.end()); } std::vector<ServerId> removed_ids; ServerNodeWithId2ServerId(_removed_sockets, &removed_ids, NULL); { BAIDU_SCOPED_LOCK(_owner->_mutex); _last_servers.swap(_servers); _owner->_last_sockets.swap(_sockets); for (std::map<NamingServiceWatcher*, const NamingServiceFilter*>::iterator it = _owner->_watchers.begin(); it != _owner->_watchers.end(); ++it) { if (!_removed_sockets.empty()) { it->first->OnRemovedServers(removed_ids); } std::vector<ServerId> added_ids; ServerNodeWithId2ServerId(_added_sockets, &added_ids, it->second); if (!_added_sockets.empty()) { it->first->OnAddedServers(added_ids); } } } for (size_t i = 0; i < _removed.size(); ++i) { SocketMapRemove(_removed[i].addr); } if (!_removed.empty() || !_added.empty()) { std::ostringstream info; info << butil::class_name_str(*_owner->_ns) << "(\"" << _owner->_service_name << "\"):"; if (!_added.empty()) { info << " added "<< _added.size(); } if (!_removed.empty()) { info << " removed " << _removed.size(); } LOG(INFO) << info.str(); } EndWait(servers.empty() ? ENODATA : 0); }