/* This is the thread function that handles the calling of callback functions if set */ thread_return_type WINAPI MQTTClient_run(void* n) { long timeout = 10L; /* first time in we have a small timeout. Gets things started more quickly */ FUNC_ENTRY; running = 1; run_id = Thread_getid(); Thread_lock_mutex(mqttclient_mutex); while (!tostop) { int rc = SOCKET_ERROR; int sock = -1; MQTTClients* m = NULL; MQTTPacket* pack = NULL; Thread_unlock_mutex(mqttclient_mutex); pack = MQTTClient_cycle(&sock, timeout, &rc); Thread_lock_mutex(mqttclient_mutex); if (tostop) break; timeout = 1000L; /* find client corresponding to socket */ if (ListFindItem(handles, &sock, clientSockCompare) == NULL) { /* assert: should not happen */ continue; } m = (MQTTClient)(handles->current->content); if (m == NULL) { /* assert: should not happen */ continue; } if (rc == SOCKET_ERROR) { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_disconnect_internal(m, 0); Thread_lock_mutex(mqttclient_mutex); } else { if (m->c->messageQueue->count > 0) { qEntry* qe = (qEntry*)(m->c->messageQueue->first->content); int topicLen = qe->topicLen; if (strlen(qe->topicName) == topicLen) topicLen = 0; Log(TRACE_MIN, -1, "Calling messageArrived for client %s, queue depth %d", m->c->clientID, m->c->messageQueue->count); Thread_unlock_mutex(mqttclient_mutex); rc = (*(m->ma))(m->context, qe->topicName, topicLen, qe->msg); Thread_lock_mutex(mqttclient_mutex); /* if 0 (false) is returned by the callback then it failed, so we don't remove the message from * the queue, and it will be retried later. If 1 is returned then the message data may have been freed, * so we must be careful how we use it. */ if (rc) ListRemove(m->c->messageQueue, qe); else Log(TRACE_MIN, -1, "False returned from messageArrived for client %s, message remains on queue", m->c->clientID); } if (pack) { if (pack->header.bits.type == CONNACK) { Log(TRACE_MIN, -1, "Posting connack semaphore for client %s", m->c->clientID); m->pack = pack; Thread_post_sem(m->connack_sem); } else if (pack->header.bits.type == SUBACK) { Log(TRACE_MIN, -1, "Posting suback semaphore for client %s", m->c->clientID); m->pack = pack; Thread_post_sem(m->suback_sem); } else if (pack->header.bits.type == UNSUBACK) { Log(TRACE_MIN, -1, "Posting unsuback semaphore for client %s", m->c->clientID); m->pack = pack; Thread_post_sem(m->unsuback_sem); } } else if (m->c->connect_state == 1 && !Thread_check_sem(m->connect_sem)) { int error; socklen_t len = sizeof(error); if ((m->rc = getsockopt(m->c->net.socket, SOL_SOCKET, SO_ERROR, (char*)&error, &len)) == 0) m->rc = error; Log(TRACE_MIN, -1, "Posting connect semaphore for client %s rc %d", m->c->clientID, m->rc); Thread_post_sem(m->connect_sem); } #if defined(OPENSSL) else if (m->c->connect_state == 2 && !Thread_check_sem(m->connect_sem)) { rc = SSLSocket_connect(m->c->net.ssl, m->c->net.socket); if (rc == 1) { if (!m->c->cleansession && m->c->session == NULL) m->c->session = SSL_get1_session(m->c->net.ssl); m->rc = rc; Log(TRACE_MIN, -1, "Posting connect semaphore for SSL client %s rc %d", m->c->clientID, m->rc); Thread_post_sem(m->connect_sem); } else if (rc == SSL_FATAL) { m->rc = rc; //tostop = 1; break; } } #endif } } run_id = 0; running = 0; Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT; return 0; }
bool KeyMap::InitializeKeyMap(const char *inifile, const char *tablefile) { AutoTable kmtable(tablefile); if (!kmtable) { return false; } char tINIkeymap[_MAX_PATH]; PathJoin( tINIkeymap, core->GamePath, inifile, NULL ); FileStream* config = FileStream::OpenFile( tINIkeymap ); if (config == NULL) { Log(WARNING, "KeyMap", "There is no '%s' file...", inifile); return false; } char name[KEYLENGTH+1], value[_MAX_PATH + 3]; while (config->Remains()) { char line[_MAX_PATH]; if (config->ReadLine(line, _MAX_PATH) == -1) break; if ((line[0] == '#') || ( line[0] == '[' ) || ( line[0] == '\r' ) || ( line[0] == '\n' ) || ( line[0] == ';' )) { continue; } name[0] = 0; value[0] = 0; //ignore possible space after the =, sadly we cannot do the same with //spaces before it if (sscanf( line, "%[^=]= %[^\r\n]", name, value )!=2) continue; strnlwrcpy(name,name,KEYLENGTH); //remove trailing spaces (bg1 ini file contains them) char *nameend = name + strlen( name ) - 1; while (nameend >= name && strchr( " \t\r\n", *nameend )) { *nameend-- = '\0'; } //change internal spaces to underscore for(int c=0;c<KEYLENGTH;c++) if (name[c]==' ') name[c]='_'; int l = strlen(value); Function *fun; void *tmp; if (l<0 || l>1 || keymap.Lookup(value, tmp) ) { print("Ignoring key %s", value); continue; } const char *module; const char *function; const char *group; if (kmtable->GetRowIndex(name)>=0 ) { module = kmtable->QueryField(name, "MODULE"); function = kmtable->QueryField(name, "FUNCTION"); group = kmtable->QueryField(name, "GROUP"); } else { module = kmtable->QueryField("Default","MODULE"); function = kmtable->QueryField("Default","FUNCTION"); group = kmtable->QueryField("Default","GROUP"); print("Adding key %s with function %s::%s", value, module, function); } fun = new Function(module, function, atoi(group)); keymap.SetAt(value, fun); } delete config; return true; }
//todo: this function is an abomination, this is just disgusting. fix it. //...seriously, this is really, really horrible. I mean this is amazingly bad. void OBS::MainCaptureLoop() { int curRenderTarget = 0, curYUVTexture = 0, curCopyTexture = 0; int copyWait = NUM_RENDER_BUFFERS-1; bSentHeaders = false; bFirstAudioPacket = true; bool bLogLongFramesProfile = GlobalConfig->GetInt(TEXT("General"), TEXT("LogLongFramesProfile"), LOGLONGFRAMESDEFAULT) != 0; float logLongFramesProfilePercentage = GlobalConfig->GetFloat(TEXT("General"), TEXT("LogLongFramesProfilePercentage"), 10.f); Vect2 baseSize = Vect2(float(baseCX), float(baseCY)); Vect2 outputSize = Vect2(float(outputCX), float(outputCY)); Vect2 scaleSize = Vect2(float(scaleCX), float(scaleCY)); HANDLE hMatrix = yuvScalePixelShader->GetParameterByName(TEXT("yuvMat")); HANDLE hScaleVal = yuvScalePixelShader->GetParameterByName(TEXT("baseDimensionI")); //---------------------------------------- // x264 input buffers int curOutBuffer = 0; bool bUsingQSV = videoEncoder->isQSV();//GlobalConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0; bUsing444 = false; EncoderPicture lastPic; EncoderPicture outPics[NUM_OUT_BUFFERS]; for(int i=0; i<NUM_OUT_BUFFERS; i++) { if(bUsingQSV) { outPics[i].mfxOut = new mfxFrameSurface1; memset(outPics[i].mfxOut, 0, sizeof(mfxFrameSurface1)); mfxFrameData& data = outPics[i].mfxOut->Data; videoEncoder->RequestBuffers(&data); } else { outPics[i].picOut = new x264_picture_t; x264_picture_init(outPics[i].picOut); } } if(bUsing444) { for(int i=0; i<NUM_OUT_BUFFERS; i++) { outPics[i].picOut->img.i_csp = X264_CSP_BGRA; //although the x264 input says BGR, x264 actually will expect packed UYV outPics[i].picOut->img.i_plane = 1; } } else { if(!bUsingQSV) for(int i=0; i<NUM_OUT_BUFFERS; i++) x264_picture_alloc(outPics[i].picOut, X264_CSP_NV12, outputCX, outputCY); } int bCongestionControl = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("CongestionControl"), 0); bool bDynamicBitrateSupported = App->GetVideoEncoder()->DynamicBitrateSupported(); int defaultBitRate = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000); int currentBitRate = defaultBitRate; QWORD lastAdjustmentTime = 0; UINT adjustmentStreamId = 0; //std::unique_ptr<ProfilerNode> encodeThreadProfiler; //---------------------------------------- // time/timestamp stuff bool bWasLaggedFrame = false; totalStreamTime = 0; lastAudioTimestamp = 0; //---------------------------------------- // start audio capture streams desktopAudio->StartCapture(); if(micAudio) micAudio->StartCapture(); //---------------------------------------- // status bar/statistics stuff DWORD fpsCounter = 0; int numLongFrames = 0; int numTotalFrames = 0; bytesPerSec = 0; captureFPS = 0; curFramesDropped = 0; curStrain = 0.0; PostMessage(hwndMain, OBS_UPDATESTATUSBAR, 0, 0); QWORD lastBytesSent[3] = {0, 0, 0}; DWORD lastFramesDropped = 0; double bpsTime = 0.0; double lastStrain = 0.0f; DWORD numSecondsWaited = 0; //---------------------------------------- // 444->420 thread data int numThreads = MAX(OSGetTotalCores()-2, 1); HANDLE *h420Threads = (HANDLE*)Allocate(sizeof(HANDLE)*numThreads); Convert444Data *convertInfo = (Convert444Data*)Allocate(sizeof(Convert444Data)*numThreads); zero(h420Threads, sizeof(HANDLE)*numThreads); zero(convertInfo, sizeof(Convert444Data)*numThreads); for(int i=0; i<numThreads; i++) { convertInfo[i].width = outputCX; convertInfo[i].height = outputCY; convertInfo[i].hSignalConvert = CreateEvent(NULL, FALSE, FALSE, NULL); convertInfo[i].hSignalComplete = CreateEvent(NULL, FALSE, FALSE, NULL); convertInfo[i].bNV12 = bUsingQSV; convertInfo[i].numThreads = numThreads; if(i == 0) convertInfo[i].startY = 0; else convertInfo[i].startY = convertInfo[i-1].endY; if(i == (numThreads-1)) convertInfo[i].endY = outputCY; else convertInfo[i].endY = ((outputCY/numThreads)*(i+1)) & 0xFFFFFFFE; } bool bEncode; bool bFirstFrame = true; bool bFirstImage = true; bool bFirstEncode = true; bool bUseThreaded420 = bUseMultithreadedOptimizations && (OSGetTotalCores() > 1) && !bUsing444; List<HANDLE> completeEvents; if(bUseThreaded420) { for(int i=0; i<numThreads; i++) { h420Threads[i] = OSCreateThread((XTHREAD)Convert444Thread, convertInfo+i); completeEvents << convertInfo[i].hSignalComplete; } } //---------------------------------------- QWORD streamTimeStart = GetQPCTimeNS(); QWORD lastStreamTime = 0; QWORD firstFrameTimeMS = streamTimeStart/1000000; QWORD frameLengthNS = 1000000000/fps; while(WaitForSingleObject(hVideoEvent, INFINITE) == WAIT_OBJECT_0) { if (bShutdownVideoThread) break; QWORD renderStartTime = GetQPCTimeNS(); totalStreamTime = DWORD((renderStartTime-streamTimeStart)/1000000); bool bRenderView = !IsIconic(hwndMain) && bRenderViewEnabled; QWORD renderStartTimeMS = renderStartTime/1000000; QWORD curStreamTime = latestVideoTimeNS; if (!lastStreamTime) lastStreamTime = curStreamTime-frameLengthNS; QWORD frameDelta = curStreamTime-lastStreamTime; //if (!lastStreamTime) // lastStreamTime = renderStartTime-frameLengthNS; //QWORD frameDelta = renderStartTime-lastStreamTime; double fSeconds = double(frameDelta)*0.000000001; //lastStreamTime = renderStartTime; profileIn("video thread frame"); //Log(TEXT("Stream Time: %llu"), curStreamTime); //Log(TEXT("frameDelta: %lf"), fSeconds); bool bUpdateBPS = false; profileIn("frame preprocessing and rendering"); //------------------------------------ if(bRequestKeyframe && keyframeWait > 0) { keyframeWait -= int(frameDelta); if(keyframeWait <= 0) { GetVideoEncoder()->RequestKeyframe(); bRequestKeyframe = false; } } if(!bPushToTalkDown && pushToTalkTimeLeft > 0) { pushToTalkTimeLeft -= int(frameDelta); OSDebugOut(TEXT("time left: %d\r\n"), pushToTalkTimeLeft); if(pushToTalkTimeLeft <= 0) { pushToTalkTimeLeft = 0; bPushToTalkOn = false; } } //------------------------------------ OSEnterMutex(hSceneMutex); if (bPleaseEnableProjector) ActuallyEnableProjector(); else if(bPleaseDisableProjector) DisableProjector(); if(bResizeRenderView) { GS->ResizeView(); bResizeRenderView = false; } //------------------------------------ if(scene) { profileIn("scene->Preprocess"); scene->Preprocess(); for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].source->Preprocess(); profileOut; scene->Tick(float(fSeconds)); for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].source->Tick(float(fSeconds)); } //------------------------------------ QWORD curBytesSent = network->GetCurrentSentBytes(); curFramesDropped = network->NumDroppedFrames(); bpsTime += fSeconds; if(bpsTime > 1.0f) { if(numSecondsWaited < 3) ++numSecondsWaited; //bytesPerSec = DWORD(curBytesSent - lastBytesSent); bytesPerSec = DWORD(curBytesSent - lastBytesSent[0]) / numSecondsWaited; if(bpsTime > 2.0) bpsTime = 0.0f; else bpsTime -= 1.0; if(numSecondsWaited == 3) { lastBytesSent[0] = lastBytesSent[1]; lastBytesSent[1] = lastBytesSent[2]; lastBytesSent[2] = curBytesSent; } else lastBytesSent[numSecondsWaited] = curBytesSent; captureFPS = fpsCounter; fpsCounter = 0; bUpdateBPS = true; } fpsCounter++; curStrain = network->GetPacketStrain(); EnableBlending(TRUE); BlendFunction(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA); //------------------------------------ // render the mini render texture LoadVertexShader(mainVertexShader); LoadPixelShader(mainPixelShader); SetRenderTarget(mainRenderTextures[curRenderTarget]); Ortho(0.0f, baseSize.x, baseSize.y, 0.0f, -100.0f, 100.0f); SetViewport(0, 0, baseSize.x, baseSize.y); if(scene) scene->Render(); //------------------------------------ if(bTransitioning) { if(!transitionTexture) { transitionTexture = CreateTexture(baseCX, baseCY, GS_BGRA, NULL, FALSE, TRUE); if(transitionTexture) { D3D10Texture *d3dTransitionTex = static_cast<D3D10Texture*>(transitionTexture); D3D10Texture *d3dSceneTex = static_cast<D3D10Texture*>(mainRenderTextures[lastRenderTarget]); GetD3D()->CopyResource(d3dTransitionTex->texture, d3dSceneTex->texture); } else bTransitioning = false; } else if(transitionAlpha >= 1.0f) { delete transitionTexture; transitionTexture = NULL; bTransitioning = false; } } if(bTransitioning) { EnableBlending(TRUE); transitionAlpha += float(fSeconds)*5.0f; if(transitionAlpha > 1.0f) transitionAlpha = 1.0f; } else EnableBlending(FALSE); //------------------------------------ // render the mini view thingy if (bProjector) { SetRenderTarget(projectorTexture); Vect2 renderFrameSize, renderFrameOffset; Vect2 projectorSize = Vect2(float(projectorWidth), float(projectorHeight)); float projectorAspect = (projectorSize.x / projectorSize.y); float baseAspect = (baseSize.x / baseSize.y); if (projectorAspect < baseAspect) { float fProjectorWidth = float(projectorWidth); renderFrameSize = Vect2(fProjectorWidth, fProjectorWidth / baseAspect); renderFrameOffset = Vect2(0.0f, (projectorSize.y-renderFrameSize.y) * 0.5f); } else { float fProjectorHeight = float(projectorHeight); renderFrameSize = Vect2(fProjectorHeight * baseAspect, fProjectorHeight); renderFrameOffset = Vect2((projectorSize.x-renderFrameSize.x) * 0.5f, 0.0f); } DrawPreview(renderFrameSize, renderFrameOffset, projectorSize, curRenderTarget, Preview_Projector); SetRenderTarget(NULL); } if(bRenderView) { // Cache const Vect2 renderFrameSize = GetRenderFrameSize(); const Vect2 renderFrameOffset = GetRenderFrameOffset(); const Vect2 renderFrameCtrlSize = GetRenderFrameControlSize(); SetRenderTarget(NULL); DrawPreview(renderFrameSize, renderFrameOffset, renderFrameCtrlSize, curRenderTarget, bFullscreenMode ? Preview_Fullscreen : Preview_Standard); //draw selections if in edit mode if(bEditMode && !bSizeChanging) { if(scene) { LoadVertexShader(solidVertexShader); LoadPixelShader(solidPixelShader); solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); scene->RenderSelections(solidPixelShader); } } } else if(bForceRenderViewErase) { InvalidateRect(hwndRenderFrame, NULL, TRUE); UpdateWindow(hwndRenderFrame); bForceRenderViewErase = false; } //------------------------------------ // actual stream output LoadVertexShader(mainVertexShader); LoadPixelShader(yuvScalePixelShader); Texture *yuvRenderTexture = yuvRenderTextures[curRenderTarget]; SetRenderTarget(yuvRenderTexture); switch(colorDesc.matrix) { case ColorMatrix_GBR: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[0] : (float*)yuvMat[0]); break; case ColorMatrix_YCgCo: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[1] : (float*)yuvMat[1]); break; case ColorMatrix_BT2020NCL: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[2] : (float*)yuvMat[2]); break; case ColorMatrix_BT709: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[3] : (float*)yuvMat[3]); break; case ColorMatrix_SMPTE240M: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[4] : (float*)yuvMat[4]); break; default: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[5] : (float*)yuvMat[5]); } if(downscale < 2.01) yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/baseSize); else if(downscale < 3.01) yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/(outputSize*3.0f)); Ortho(0.0f, outputSize.x, outputSize.y, 0.0f, -100.0f, 100.0f); SetViewport(0.0f, 0.0f, outputSize.x, outputSize.y); //why am I using scaleSize instead of outputSize for the texture? //because outputSize can be trimmed by up to three pixels due to 128-bit alignment. //using the scale function with outputSize can cause slightly inaccurate scaled images if(bTransitioning) { BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO); DrawSpriteEx(transitionTexture, 0xFFFFFFFF, 0.0f, 0.0f, scaleSize.x, scaleSize.y, 0.0f, 0.0f, 1.0f, 1.0f); BlendFunction(GS_BLEND_FACTOR, GS_BLEND_INVFACTOR, transitionAlpha); } DrawSpriteEx(mainRenderTextures[curRenderTarget], 0xFFFFFFFF, 0.0f, 0.0f, outputSize.x, outputSize.y, 0.0f, 0.0f, 1.0f, 1.0f); //------------------------------------ if (bProjector && !copyWait) projectorSwap->Present(0, 0); if(bRenderView && !copyWait) static_cast<D3D10System*>(GS)->swap->Present(0, 0); OSLeaveMutex(hSceneMutex); profileOut; //------------------------------------ // present/upload profileIn("GPU download and color conversion"); bEncode = true; if(copyWait) { copyWait--; bEncode = false; } else { //audio sometimes takes a bit to start -- do not start processing frames until audio has started capturing if(!bRecievedFirstAudioFrame) { static bool bWarnedAboutNoAudio = false; if (renderStartTimeMS-firstFrameTimeMS > 10000 && !bWarnedAboutNoAudio) { bWarnedAboutNoAudio = true; //AddStreamInfo (TEXT ("WARNING: OBS is not receiving audio frames. Please check your audio devices."), StreamInfoPriority_Critical); } bEncode = false; } else if(bFirstFrame) { firstFrameTimestamp = lastStreamTime/1000000; bFirstFrame = false; } if(!bEncode) { if(curYUVTexture == (NUM_RENDER_BUFFERS-1)) curYUVTexture = 0; else curYUVTexture++; } } lastStreamTime = curStreamTime; if(bEncode) { UINT prevCopyTexture = (curCopyTexture == 0) ? NUM_RENDER_BUFFERS-1 : curCopyTexture-1; ID3D10Texture2D *copyTexture = copyTextures[curCopyTexture]; profileIn("CopyResource"); if(!bFirstEncode && bUseThreaded420) { WaitForMultipleObjects(completeEvents.Num(), completeEvents.Array(), TRUE, INFINITE); copyTexture->Unmap(0); } D3D10Texture *d3dYUV = static_cast<D3D10Texture*>(yuvRenderTextures[curYUVTexture]); GetD3D()->CopyResource(copyTexture, d3dYUV->texture); profileOut; ID3D10Texture2D *prevTexture = copyTextures[prevCopyTexture]; if(bFirstImage) //ignore the first frame bFirstImage = false; else { HRESULT result; D3D10_MAPPED_TEXTURE2D map; if(SUCCEEDED(result = prevTexture->Map(0, D3D10_MAP_READ, 0, &map))) { int prevOutBuffer = (curOutBuffer == 0) ? NUM_OUT_BUFFERS-1 : curOutBuffer-1; int nextOutBuffer = (curOutBuffer == NUM_OUT_BUFFERS-1) ? 0 : curOutBuffer+1; EncoderPicture &prevPicOut = outPics[prevOutBuffer]; EncoderPicture &picOut = outPics[curOutBuffer]; EncoderPicture &nextPicOut = outPics[nextOutBuffer]; if(!bUsing444) { profileIn("conversion to 4:2:0"); if(bUseThreaded420) { for(int i=0; i<numThreads; i++) { convertInfo[i].input = (LPBYTE)map.pData; convertInfo[i].inPitch = map.RowPitch; if(bUsingQSV) { mfxFrameData& data = nextPicOut.mfxOut->Data; videoEncoder->RequestBuffers(&data); convertInfo[i].outPitch = data.Pitch; convertInfo[i].output[0] = data.Y; convertInfo[i].output[1] = data.UV; } else { convertInfo[i].output[0] = nextPicOut.picOut->img.plane[0]; convertInfo[i].output[1] = nextPicOut.picOut->img.plane[1]; convertInfo[i].output[2] = nextPicOut.picOut->img.plane[2]; } SetEvent(convertInfo[i].hSignalConvert); } if(bFirstEncode) bFirstEncode = bEncode = false; } else { if(bUsingQSV) { mfxFrameData& data = picOut.mfxOut->Data; videoEncoder->RequestBuffers(&data); LPBYTE output[] = {data.Y, data.UV}; Convert444toNV12((LPBYTE)map.pData, outputCX, map.RowPitch, data.Pitch, outputCY, 0, outputCY, output); } else Convert444toNV12((LPBYTE)map.pData, outputCX, map.RowPitch, outputCX, outputCY, 0, outputCY, picOut.picOut->img.plane); prevTexture->Unmap(0); } profileOut; } if(bEncode) { //encodeThreadProfiler.reset(::new ProfilerNode(TEXT("EncodeThread"), true)); //encodeThreadProfiler->MonitorThread(hEncodeThread); curFramePic = &picOut; } curOutBuffer = nextOutBuffer; } else { //We have to crash, or we end up deadlocking the thread when the convert threads are never signalled if (result == DXGI_ERROR_DEVICE_REMOVED) { String message; HRESULT reason = GetD3D()->GetDeviceRemovedReason(); switch (reason) { case DXGI_ERROR_DEVICE_RESET: case DXGI_ERROR_DEVICE_HUNG: message = TEXT("Your video card or driver froze and was reset. Please check for possible hardware / driver issues."); break; case DXGI_ERROR_DEVICE_REMOVED: message = TEXT("Your video card disappeared from the system. Please check for possible hardware / driver issues."); break; case DXGI_ERROR_DRIVER_INTERNAL_ERROR: message = TEXT("Your video driver reported an internal error. Please check for possible hardware / driver issues."); break; case DXGI_ERROR_INVALID_CALL: message = TEXT("Your video driver reported an invalid call. Please check for possible driver issues."); break; default: message = TEXT("DXGI_ERROR_DEVICE_REMOVED"); break; } message << TEXT(" This error can also occur if you have enabled opencl in x264 custom settings."); CrashError (TEXT("Texture->Map failed: 0x%08x 0x%08x\r\n\r\n%s"), result, reason, message.Array()); } else CrashError (TEXT("Texture->Map failed: 0x%08x"), result); } } if(curCopyTexture == (NUM_RENDER_BUFFERS-1)) curCopyTexture = 0; else curCopyTexture++; if(curYUVTexture == (NUM_RENDER_BUFFERS-1)) curYUVTexture = 0; else curYUVTexture++; if (bCongestionControl && bDynamicBitrateSupported && !bTestStream) { if (curStrain > 25) { if (renderStartTimeMS - lastAdjustmentTime > 1500) { if (currentBitRate > 100) { currentBitRate = (int)(currentBitRate * (1.0 - (curStrain / 400))); App->GetVideoEncoder()->SetBitRate(currentBitRate, -1); if (!adjustmentStreamId) adjustmentStreamId = App->AddStreamInfo (FormattedString(TEXT("Congestion detected, dropping bitrate to %d kbps"), currentBitRate).Array(), StreamInfoPriority_Low); else App->SetStreamInfo(adjustmentStreamId, FormattedString(TEXT("Congestion detected, dropping bitrate to %d kbps"), currentBitRate).Array()); bUpdateBPS = true; } lastAdjustmentTime = renderStartTimeMS; } } else if (currentBitRate < defaultBitRate && curStrain < 5 && lastStrain < 5) { if (renderStartTimeMS - lastAdjustmentTime > 5000) { if (currentBitRate < defaultBitRate) { currentBitRate += (int)(defaultBitRate * 0.05); if (currentBitRate > defaultBitRate) currentBitRate = defaultBitRate; } App->GetVideoEncoder()->SetBitRate(currentBitRate, -1); /*if (!adjustmentStreamId) App->AddStreamInfo (FormattedString(TEXT("Congestion clearing, raising bitrate to %d kbps"), currentBitRate).Array(), StreamInfoPriority_Low); else App->SetStreamInfo(adjustmentStreamId, FormattedString(TEXT("Congestion clearing, raising bitrate to %d kbps"), currentBitRate).Array());*/ bUpdateBPS = true; lastAdjustmentTime = renderStartTimeMS; } } } } lastRenderTarget = curRenderTarget; if(curRenderTarget == (NUM_RENDER_BUFFERS-1)) curRenderTarget = 0; else curRenderTarget++; if(bUpdateBPS || !CloseDouble(curStrain, lastStrain) || curFramesDropped != lastFramesDropped) { PostMessage(hwndMain, OBS_UPDATESTATUSBAR, 0, 0); lastStrain = curStrain; lastFramesDropped = curFramesDropped; } //------------------------------------ // we're about to sleep so we should flush the d3d command queue profileIn("flush"); GetD3D()->Flush(); profileOut; profileOut; //video encoding and uploading profileOut; //frame //------------------------------------ // frame sync QWORD renderStopTime = GetQPCTimeNS(); if(bWasLaggedFrame = (frameDelta > frameLengthNS)) { numLongFrames++; if(bLogLongFramesProfile && (numLongFrames/float(max(1, numTotalFrames)) * 100.) > logLongFramesProfilePercentage) DumpLastProfileData(); } //OSDebugOut(TEXT("Frame adjust time: %d, "), frameTimeAdjust-totalTime); numTotalFrames++; } DisableProjector(); //encodeThreadProfiler.reset(); if(!bUsing444) { if(bUseThreaded420) { for(int i=0; i<numThreads; i++) { if(h420Threads[i]) { convertInfo[i].bKillThread = true; SetEvent(convertInfo[i].hSignalConvert); OSTerminateThread(h420Threads[i], 10000); h420Threads[i] = NULL; } if(convertInfo[i].hSignalConvert) { CloseHandle(convertInfo[i].hSignalConvert); convertInfo[i].hSignalConvert = NULL; } if(convertInfo[i].hSignalComplete) { CloseHandle(convertInfo[i].hSignalComplete); convertInfo[i].hSignalComplete = NULL; } } if(!bFirstEncode) { ID3D10Texture2D *copyTexture = copyTextures[curCopyTexture]; copyTexture->Unmap(0); } } if(bUsingQSV) for(int i = 0; i < NUM_OUT_BUFFERS; i++) delete outPics[i].mfxOut; else for(int i=0; i<NUM_OUT_BUFFERS; i++) { x264_picture_clean(outPics[i].picOut); delete outPics[i].picOut; } } Free(h420Threads); Free(convertInfo); Log(TEXT("Total frames rendered: %d, number of late frames: %d (%0.2f%%) (it's okay for some frames to be late)"), numTotalFrames, numLongFrames, (double(numLongFrames)/double(numTotalFrames))*100.0); }
int SQLI_compose_static_queries() { int primitives=0, set_primitives=0, set_event_primitives=0, have_flows=0; if (config.what_to_count & COUNT_FLOWS || (config.sql_table_version >= 4 && config.sql_table_version < SQL_TABLE_VERSION_BGP && !config.sql_optimize_clauses)) { config.what_to_count |= COUNT_FLOWS; have_flows = TRUE; if ((config.sql_table_version < 4 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !config.sql_optimize_clauses) { Log(LOG_ERR, "ERROR ( %s/%s ): The accounting of flows requires SQL table v4. Exiting.\n", config.name, config.type); exit_plugin(1); } } /* "INSERT INTO ... VALUES ... " and "... WHERE ..." stuff */ strncpy(where[primitives].string, " WHERE ", sizeof(where[primitives].string)); snprintf(insert_clause, sizeof(insert_clause), "INSERT INTO %s (", config.sql_table); strncpy(values[primitives].string, " VALUES (", sizeof(values[primitives].string)); primitives = SQLI_evaluate_history(primitives); primitives = sql_evaluate_primitives(primitives); strncpy(insert_counters_clause, ", packets, bytes", SPACELEFT(insert_counters_clause)); if (have_flows) strncat(insert_counters_clause, ", flows", SPACELEFT(insert_counters_clause)); strncat(insert_counters_clause, ")", SPACELEFT(insert_counters_clause)); strncpy(insert_nocounters_clause, ")", SPACELEFT(insert_nocounters_clause)); /* "LOCK ..." stuff */ if (config.sql_locking_style) Log(LOG_WARNING, "WARN ( %s/%s ): sql_locking_style is not supported. Ignored.\n", config.name, config.type); snprintf(lock_clause, sizeof(lock_clause), "BEGIN", config.sql_table); strncpy(unlock_clause, "COMMIT", sizeof(unlock_clause)); /* "UPDATE ... SET ..." stuff */ snprintf(update_clause, sizeof(update_clause), "UPDATE %s ", config.sql_table); set_primitives = sql_compose_static_set(have_flows); set_event_primitives = sql_compose_static_set_event(); if (config.sql_history) { if (!config.sql_history_since_epoch) { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=DATETIME('now', 'localtime')", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; if (set_event_primitives) strncpy(set_event[set_event_primitives].string, ", ", SPACELEFT(set_event[set_event_primitives].string)); else strncpy(set_event[set_event_primitives].string, "SET ", SPACELEFT(set_event[set_event_primitives].string)); strncat(set_event[set_event_primitives].string, "stamp_updated=DATETIME('now', 'localtime')", SPACELEFT(set_event[set_event_primitives].string)); set_event[set_event_primitives].type = TIMESTAMP; set_event[set_event_primitives].handler = count_noop_setclause_event_handler; set_event_primitives++; } else { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=STRFTIME('%%s', 'now')", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; if (set_event_primitives) strncpy(set_event[set_event_primitives].string, ", ", SPACELEFT(set_event[set_event_primitives].string)); else strncpy(set_event[set_event_primitives].string, "SET ", SPACELEFT(set_event[set_event_primitives].string)); strncat(set_event[set_event_primitives].string, "stamp_updated=STRFTIME('%%s', 'now')", SPACELEFT(set_event[set_event_primitives].string)); set_event[set_event_primitives].type = TIMESTAMP; set_event[set_event_primitives].handler = count_noop_setclause_event_handler; set_event_primitives++; } } return primitives; }
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, int sceneResID, int sensorResID, int samplerResID) { SamplingIntegrator::preprocess(scene, queue, job, sceneResID, sensorResID, samplerResID); /* Create a deterministic sampler for the photon gathering step */ ref<Scheduler> sched = Scheduler::getInstance(); ref<Sampler> sampler = static_cast<Sampler *> (PluginManager::getInstance()-> createObject(MTS_CLASS(Sampler), Properties("halton"))); /* Create a sampler instance for every core */ std::vector<SerializableObject *> samplers(sched->getCoreCount()); for (size_t i=0; i<sched->getCoreCount(); ++i) { ref<Sampler> clonedSampler = sampler->clone(); clonedSampler->incRef(); samplers[i] = clonedSampler.get(); } int qmcSamplerID = sched->registerMultiResource(samplers); for (size_t i=0; i<samplers.size(); ++i) samplers[i]->decRef(); const ref_vector<Medium> &media = scene->getMedia(); for (ref_vector<Medium>::const_iterator it = media.begin(); it != media.end(); ++it) { if (!(*it)->isHomogeneous()) Log(EError, "Inhomogeneous media are currently not supported by the photon mapper!"); } if (m_globalPhotonMap.get() == NULL && m_globalPhotons > 0) { /* Generate the global photon map */ ref<GatherPhotonProcess> proc = new GatherPhotonProcess( GatherPhotonProcess::ESurfacePhotons, m_globalPhotons, m_granularity, m_maxDepth-1, m_rrDepth, m_gatherLocally, m_autoCancelGathering, job); proc->bindResource("scene", sceneResID); proc->bindResource("sensor", sensorResID); proc->bindResource("sampler", qmcSamplerID); m_proc = proc; sched->schedule(proc); sched->wait(proc); m_proc = NULL; if (proc->getReturnStatus() != ParallelProcess::ESuccess) return false; ref<PhotonMap> globalPhotonMap = proc->getPhotonMap(); if (globalPhotonMap->isFull()) { Log(EDebug, "Global photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: " SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons()); m_globalPhotonMap = globalPhotonMap; m_globalPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); m_globalPhotonMap->build(); m_globalPhotonMapID = sched->registerResource(m_globalPhotonMap); } } if (m_causticPhotonMap.get() == NULL && m_causticPhotons > 0) { /* Generate the caustic photon map */ ref<GatherPhotonProcess> proc = new GatherPhotonProcess( GatherPhotonProcess::ECausticPhotons, m_causticPhotons, m_granularity, m_maxDepth-1, m_rrDepth, m_gatherLocally, m_autoCancelGathering, job); proc->bindResource("scene", sceneResID); proc->bindResource("sensor", sensorResID); proc->bindResource("sampler", qmcSamplerID); m_proc = proc; sched->schedule(proc); sched->wait(proc); m_proc = NULL; if (proc->getReturnStatus() != ParallelProcess::ESuccess) return false; ref<PhotonMap> causticPhotonMap = proc->getPhotonMap(); if (causticPhotonMap->isFull()) { Log(EDebug, "Caustic photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: " SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons()); m_causticPhotonMap = causticPhotonMap; m_causticPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); m_causticPhotonMap->build(); m_causticPhotonMapID = sched->registerResource(m_causticPhotonMap); } } size_t volumePhotons = scene->getMedia().size() == 0 ? 0 : m_volumePhotons; if (m_volumePhotonMap.get() == NULL && volumePhotons > 0) { /* Generate the volume photon map */ ref<GatherPhotonProcess> proc = new GatherPhotonProcess( GatherPhotonProcess::EVolumePhotons, volumePhotons, m_granularity, m_maxDepth-1, m_rrDepth, m_gatherLocally, m_autoCancelGathering, job); proc->bindResource("scene", sceneResID); proc->bindResource("sensor", sensorResID); proc->bindResource("sampler", qmcSamplerID); m_proc = proc; sched->schedule(proc); sched->wait(proc); m_proc = NULL; if (proc->getReturnStatus() != ParallelProcess::ESuccess) return false; ref<PhotonMap> volumePhotonMap = proc->getPhotonMap(); if (volumePhotonMap->isFull()) { Log(EDebug, "Volume photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: " SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons()); volumePhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); volumePhotonMap->build(); m_bre = new BeamRadianceEstimator(volumePhotonMap, m_volumeLookupSize); m_breID = sched->registerResource(m_bre); } } /* Adapt to scene extents */ m_globalLookupRadius = m_globalLookupRadiusRel * scene->getBSphere().radius; m_causticLookupRadius = m_causticLookupRadiusRel * scene->getBSphere().radius; sched->unregisterResource(qmcSamplerID); return true; }
int InitializeOpenCL(void) { if (numDevices != -12345) return numDevices; numDevices = -1; /* assume detection failure for now */ cl_uint devicesDetected = 0; cl_uint numPlatforms; cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); if (status != CL_SUCCESS) { Log("Error obtaining number of platforms (clGetPlatformIDs/1)\n"); ocl_diagnose(status, NULL, NULL); // decode error code only } if (status == CL_SUCCESS) { cl_platform_id *platforms = NULL; cl_device_id *devices = NULL; if (numPlatforms != 0) { // Allocate enough space for each platform platforms = (cl_platform_id *) malloc(numPlatforms * sizeof(cl_platform_id)); // Fill in platforms with clGetPlatformIDs() status = clGetPlatformIDs(numPlatforms, platforms, NULL); if (status != CL_SUCCESS) { Log("Error obtaining list of platforms (clGetPlatformIDs/2)\n"); ocl_diagnose(status, NULL, NULL); // decode error code only } else { // Use clGetDeviceIDs() to retrieve the number of devices present for (cl_uint plat = 0; plat < numPlatforms; plat++) { cl_uint devcnt; status = clGetDeviceIDs(platforms[plat], CL_DEVICE_TYPE_GPU, 0, NULL, &devcnt); if (status == CL_DEVICE_NOT_FOUND) // Special case. No GPU devices but other may exist { status = CL_SUCCESS; devcnt = 0; } if (status != CL_SUCCESS) { Log("Error obtaining number of devices on platform %u (clGetDeviceIDs/1)\n", plat); ocl_diagnose(status, NULL, NULL); // decode error code only break; } devicesDetected += devcnt; } } } if (status == CL_SUCCESS && devicesDetected != 0) { // Allocate enough space for each device devices = (cl_device_id*) malloc(devicesDetected * sizeof(cl_device_id)); // Allocate and zero space for ocl_context ocl_context = (ocl_context_t*) calloc(devicesDetected, sizeof(ocl_context_t)); // Fill in devices with clGetDeviceIDs() cl_uint offset = 0; for (cl_uint plat = 0; plat < numPlatforms; plat++) { cl_uint devcnt; if (offset >= devicesDetected) /* Avoid call with bufferSize=0 for last platform without GPU devices */ break; status = clGetDeviceIDs(platforms[plat], CL_DEVICE_TYPE_GPU, devicesDetected - offset, devices + offset, &devcnt); if (status == CL_DEVICE_NOT_FOUND) // Special case. No GPU devices but other may exist { status = CL_SUCCESS; devcnt = 0; } if (status != CL_SUCCESS) { Log("Error obtaining list of devices on platform %u (clGetDeviceIDs/2)\n", plat); ocl_diagnose(status, NULL, NULL); // decode error code only break; } // Fill non-zero context fields for each device for (cl_uint u = 0; u < devcnt; u++, offset++) { ocl_context_t *cont = &ocl_context[offset]; /* Assume it working for now */ cont->active = true; cont->coreID = CORE_NONE; cont->platformID = platforms[plat]; cont->deviceID = devices[offset]; cont->firstOnPlatform = (u == 0); cont->clientDeviceNo = offset; cont->runSize = 65536; cont->runSizeMultiplier = 64; cont->maxWorkSize = 2048 * 2048; /* Sanity check: size_t must be same width for both client and device */ /* Re-reading OpenCL specs, I found this check too paranoid. If implemented correctly, difference in bitness must only limit maximum number of iterations allowed to be requested from kernel (i.e. 64-bit host cannot request more then 0xFFFFFFFF iterations from "32-bit" device. Client always requests lesser value. So only log a message, just in case. */ cl_uint devbits; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_ADDRESS_BITS, sizeof(devbits), &devbits, NULL); #if 0 /* Disabled, too paranoid */ if (ocl_diagnose(status, "clGetDeviceInfo(CL_DEVICE_ADDRESS_BITS)", cont) != CL_SUCCESS) cont->active = false; else if (devbits != sizeof(size_t) * 8) { Log("Error: Bitness of device %u (%u) does not match CPU (%u)!\n", offset, devbits, (unsigned)(sizeof(size_t) * 8)); cont->active = false; } #else if (ocl_diagnose(status, "clGetDeviceInfo(CL_DEVICE_ADDRESS_BITS)", cont) == CL_SUCCESS && devbits != sizeof(size_t) * 8) Log("size_t on device %u: %u bits, host: %u\n", offset, devbits, (unsigned)(sizeof(size_t) * 8)); #endif } } } if (status == CL_SUCCESS) { // Everything is done. Apply configuration. numDevices = devicesDetected; } // Don't need them anymore if (devices) free(devices); if (platforms) free(platforms); } return numDevices; }
/* Functions */ void sqlite3_plugin(int pipe_fd, struct configuration *cfgptr, void *ptr) { struct pkt_data *data; struct ports_table pt; struct pollfd pfd; struct insert_data idata; time_t refresh_deadline; int timeout, refresh_timeout, amqp_timeout; int ret, num; struct ring *rg = &((struct channels_list_entry *)ptr)->rg; struct ch_status *status = ((struct channels_list_entry *)ptr)->status; struct plugins_list_entry *plugin_data = ((struct channels_list_entry *)ptr)->plugin; int datasize = ((struct channels_list_entry *)ptr)->datasize; u_int32_t bufsz = ((struct channels_list_entry *)ptr)->bufsize; pid_t core_pid = ((struct channels_list_entry *)ptr)->core_pid; struct networks_file_data nfd; char *dataptr; unsigned char *rgptr; int pollagain = TRUE; u_int32_t seq = 1, rg_err_count = 0; struct extra_primitives extras; struct primitives_ptrs prim_ptrs; #ifdef WITH_RABBITMQ struct p_amqp_host *amqp_host = &((struct channels_list_entry *)ptr)->amqp_host; #endif memcpy(&config, cfgptr, sizeof(struct configuration)); memcpy(&extras, &((struct channels_list_entry *)ptr)->extras, sizeof(struct extra_primitives)); recollect_pipe_memory(ptr); pm_setproctitle("%s [%s]", "SQLite3 Plugin", config.name); memset(&idata, 0, sizeof(idata)); if (config.pidfile) write_pid_file_plugin(config.pidfile, config.type, config.name); if (config.logfile) { fclose(config.logfile_fd); config.logfile_fd = open_output_file(config.logfile, "a", FALSE); } sql_set_signals(); sql_init_default_values(&extras); SQLI_init_default_values(&idata); SQLI_set_callbacks(&sqlfunc_cbr); sql_set_insert_func(); /* some LOCAL initialization AFTER setting some default values */ reload_map = FALSE; idata.now = time(NULL); refresh_deadline = idata.now; idata.cfg = &config; sql_init_maps(&extras, &prim_ptrs, &nt, &nc, &pt); sql_init_global_buffers(); sql_init_historical_acct(idata.now, &idata); sql_init_triggers(idata.now, &idata); sql_init_refresh_deadline(&refresh_deadline); if (config.pipe_amqp) { plugin_pipe_amqp_compile_check(); #ifdef WITH_RABBITMQ pipe_fd = plugin_pipe_amqp_connect_to_consume(amqp_host, plugin_data); amqp_timeout = plugin_pipe_set_retry_timeout(&amqp_host->btimers, pipe_fd); #endif } else setnonblocking(pipe_fd); /* setting number of entries in _protocols structure */ while (_protocols[protocols_number].number != -1) protocols_number++; /* building up static SQL clauses */ idata.num_primitives = SQLI_compose_static_queries(); glob_num_primitives = idata.num_primitives; /* setting up environment variables */ SQL_SetENV(); sql_link_backend_descriptors(&bed, &p, &b); /* plugin main loop */ for(;;) { poll_again: status->wakeup = TRUE; calc_refresh_timeout(refresh_deadline, idata.now, &refresh_timeout); pfd.fd = pipe_fd; pfd.events = POLLIN; timeout = MIN(refresh_timeout, (amqp_timeout ? amqp_timeout : INT_MAX)); ret = poll(&pfd, (pfd.fd == ERR ? 0 : 1), timeout); if (ret <= 0) { if (getppid() == 1) { Log(LOG_ERR, "ERROR ( %s/%s ): Core process *seems* gone. Exiting.\n", config.name, config.type); exit_plugin(1); } if (ret < 0) goto poll_again; } idata.now = time(NULL); if (config.sql_history) { while (idata.now > (idata.basetime + idata.timeslot)) { time_t saved_basetime = idata.basetime; idata.basetime += idata.timeslot; if (config.sql_history == COUNT_MONTHLY) idata.timeslot = calc_monthly_timeslot(idata.basetime, config.sql_history_howmany, ADD); glob_basetime = idata.basetime; idata.new_basetime = saved_basetime; glob_new_basetime = saved_basetime; } } #ifdef WITH_RABBITMQ if (config.pipe_amqp && pipe_fd == ERR) { if (timeout == amqp_timeout) { pipe_fd = plugin_pipe_amqp_connect_to_consume(amqp_host, plugin_data); amqp_timeout = plugin_pipe_set_retry_timeout(&amqp_host->btimers, pipe_fd); } else amqp_timeout = plugin_pipe_calc_retry_timeout_diff(&amqp_host->btimers, idata.now); } #endif switch (ret) { case 0: /* timeout */ if (qq_ptr) sql_cache_flush(queries_queue, qq_ptr, &idata, FALSE); sql_cache_handle_flush_event(&idata, &refresh_deadline, &pt); break; default: /* we received data */ read_data: if (!config.pipe_amqp) { if (!pollagain) { seq++; seq %= MAX_SEQNUM; if (seq == 0) rg_err_count = FALSE; idata.now = time(NULL); } else { if ((ret = read(pipe_fd, &rgptr, sizeof(rgptr))) == 0) exit_plugin(1); /* we exit silently; something happened at the write end */ } if ((rg->ptr + bufsz) > rg->end) rg->ptr = rg->base; if (((struct ch_buf_hdr *)rg->ptr)->seq != seq) { if (!pollagain) { pollagain = TRUE; goto poll_again; } else { rg_err_count++; if (config.debug || (rg_err_count > MAX_RG_COUNT_ERR)) { Log(LOG_WARNING, "WARN ( %s/%s ): Missing data detected (plugin_buffer_size=%llu plugin_pipe_size=%llu).\n", config.name, config.type, config.buffer_size, config.pipe_size); Log(LOG_WARNING, "WARN ( %s/%s ): Increase values or look for plugin_buffer_size, plugin_pipe_size in CONFIG-KEYS document.\n\n", config.name, config.type); } seq = ((struct ch_buf_hdr *)rg->ptr)->seq; } } pollagain = FALSE; memcpy(pipebuf, rg->ptr, bufsz); rg->ptr += bufsz; } #ifdef WITH_RABBITMQ else { ret = p_amqp_consume_binary(amqp_host, pipebuf, config.buffer_size); if (ret) pipe_fd = ERR; seq = ((struct ch_buf_hdr *)pipebuf)->seq; amqp_timeout = plugin_pipe_set_retry_timeout(&amqp_host->btimers, pipe_fd); } #endif /* lazy sql refresh handling */ if (idata.now > refresh_deadline) { if (qq_ptr) sql_cache_flush(queries_queue, qq_ptr, &idata, FALSE); sql_cache_handle_flush_event(&idata, &refresh_deadline, &pt); } else { if (config.sql_trigger_exec) { while (idata.now > idata.triggertime && idata.t_timeslot > 0) { sql_trigger_exec(config.sql_trigger_exec); idata.triggertime += idata.t_timeslot; if (config.sql_trigger_time == COUNT_MONTHLY) idata.t_timeslot = calc_monthly_timeslot(idata.triggertime, config.sql_trigger_time_howmany, ADD); } } } data = (struct pkt_data *) (pipebuf+sizeof(struct ch_buf_hdr)); if (config.debug_internal_msg) Log(LOG_DEBUG, "DEBUG ( %s/%s ): buffer received cpid=%u seq=%u num_entries=%u\n", config.name, config.type, core_pid, seq, ((struct ch_buf_hdr *)pipebuf)->num); if (!config.pipe_check_core_pid || ((struct ch_buf_hdr *)pipebuf)->core_pid == core_pid) { while (((struct ch_buf_hdr *)pipebuf)->num > 0) { for (num = 0; primptrs_funcs[num]; num++) (*primptrs_funcs[num])((u_char *)data, &extras, &prim_ptrs); for (num = 0; net_funcs[num]; num++) (*net_funcs[num])(&nt, &nc, &data->primitives, prim_ptrs.pbgp, &nfd); if (config.ports_file) { if (!pt.table[data->primitives.src_port]) data->primitives.src_port = 0; if (!pt.table[data->primitives.dst_port]) data->primitives.dst_port = 0; } if (config.pkt_len_distrib_bins_str && config.what_to_count_2 & COUNT_PKT_LEN_DISTRIB) evaluate_pkt_len_distrib(data); prim_ptrs.data = data; (*insert_func)(&prim_ptrs, &idata); ((struct ch_buf_hdr *)pipebuf)->num--; if (((struct ch_buf_hdr *)pipebuf)->num) { dataptr = (unsigned char *) data; if (!prim_ptrs.vlen_next_off) dataptr += datasize; else dataptr += prim_ptrs.vlen_next_off; data = (struct pkt_data *) dataptr; } } } if (!config.pipe_amqp) goto read_data; } } }
static bool Render(Writer *out, const char *start, const char *input, Seq *hash_stack, char *delim_start, size_t *delim_start_len, char *delim_end, size_t *delim_end_len, bool skip_content, const char *section, const char **section_end) { while (true) { Mustache tag = NextTag(input, delim_start, *delim_start_len, delim_end, *delim_end_len); { const char *line_begin = NULL; const char *line_end = NULL; if (!IsTagTypeRenderable(tag.type) && IsTagStandalone(start, tag.begin, tag.end, &line_begin, &line_end)) { RenderContent(out, input, line_begin - input, false, skip_content); input = line_end; } else { RenderContent(out, input, tag.begin - input, false, skip_content); input = tag.end; } } switch (tag.type) { case TAG_TYPE_ERR: return false; case TAG_TYPE_DELIM: if (!SetDelimiters(tag.content, tag.content_len, delim_start, delim_start_len, delim_end, delim_end_len)) { return false; } continue; case TAG_TYPE_COMMENT: continue; case TAG_TYPE_NONE: return true; case TAG_TYPE_VAR_UNESCAPED: case TAG_TYPE_VAR: if (!skip_content) { if (tag.content_len > 0) { if (!RenderVariable(out, tag.content, tag.content_len, tag.type == TAG_TYPE_VAR, hash_stack)) { return false; } } else { RenderContent(out, delim_start, *delim_start_len, false, false); RenderContent(out, delim_end, *delim_end_len, false, false); } } continue; case TAG_TYPE_INVERTED: case TAG_TYPE_SECTION: { char *section = xstrndup(tag.content, tag.content_len); JsonElement *var = LookupVariable(hash_stack, tag.content, tag.content_len); SeqAppend(hash_stack, var); if (!var) { const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type != TAG_TYPE_INVERTED, section, &cur_section_end)) { free(section); return false; } free(section); input = cur_section_end; continue; } switch (JsonGetElementType(var)) { case JSON_ELEMENT_TYPE_PRIMITIVE: switch (JsonGetPrimitiveType(var)) { case JSON_PRIMITIVE_TYPE_BOOL: { bool skip = skip_content || (!JsonPrimitiveGetAsBool(var) ^ (tag.type == TAG_TYPE_INVERTED)); const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, skip, section, &cur_section_end)) { free(section); return false; } free(section); input = cur_section_end; } continue; default: assert(false); return false; } break; case JSON_ELEMENT_TYPE_CONTAINER: switch (JsonGetContrainerType(var)) { case JSON_CONTAINER_TYPE_OBJECT: { const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type == TAG_TYPE_INVERTED, section, &cur_section_end)) { free(section); return false; } free(section); input = cur_section_end; } break; case JSON_CONTAINER_TYPE_ARRAY: if (JsonLength(var) > 0) { const char *cur_section_end = NULL; for (size_t i = 0; i < JsonLength(var); i++) { JsonElement *child_hash = JsonAt(var, i); SeqAppend(hash_stack, child_hash); if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type == TAG_TYPE_INVERTED, section, &cur_section_end)) { free(section); return false; } } input = cur_section_end; free(section); } else { const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, tag.type != TAG_TYPE_INVERTED, section, &cur_section_end)) { free(section); return false; } free(section); input = cur_section_end; } break; } break; } } continue; case TAG_TYPE_SECTION_END: if (!section) { char *varname = xstrndup(tag.content, tag.content_len); Log(LOG_LEVEL_WARNING, "Unknown section close in mustache template '%s'", varname); free(varname); return false; } else { SeqRemove(hash_stack, SeqLength(hash_stack) - 1); *section_end = input; return true; } break; default: assert(false); return false; } } assert(false); }
/** * Writes to a register. * * @returns VBox status code. * VERR_MORE_DATA if a command is ready to be sent to the SCSI driver. * @param pVBoxSCSI Pointer to the SCSI state. * @param iRegister Index of the register to write to. * @param uVal Value to write. */ int vboxscsiWriteRegister(PVBOXSCSI pVBoxSCSI, uint8_t iRegister, uint8_t uVal) { int rc = VINF_SUCCESS; switch (iRegister) { case 0: { if (pVBoxSCSI->enmState == VBOXSCSISTATE_NO_COMMAND) { pVBoxSCSI->enmState = VBOXSCSISTATE_READ_TXDIR; pVBoxSCSI->uTargetDevice = uVal; } else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_TXDIR) { if (uVal != VBOXSCSI_TXDIR_FROM_DEVICE && uVal != VBOXSCSI_TXDIR_TO_DEVICE) vboxscsiReset(pVBoxSCSI); else { pVBoxSCSI->enmState = VBOXSCSISTATE_READ_CDB_SIZE; pVBoxSCSI->uTxDir = uVal; } } else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_CDB_SIZE) { if (uVal > VBOXSCSI_CDB_SIZE_MAX) vboxscsiReset(pVBoxSCSI); else { pVBoxSCSI->enmState = VBOXSCSISTATE_READ_BUFFER_SIZE_LOW; pVBoxSCSI->cbCDB = uVal; } } else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_BUFFER_SIZE_LOW) { pVBoxSCSI->enmState = VBOXSCSISTATE_READ_BUFFER_SIZE_HIGH; pVBoxSCSI->cbBuf = uVal; } else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_BUFFER_SIZE_HIGH) { pVBoxSCSI->enmState = VBOXSCSISTATE_READ_COMMAND; pVBoxSCSI->cbBuf |= (((uint16_t)uVal) << 8); } else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_COMMAND) { pVBoxSCSI->aCDB[pVBoxSCSI->iCDB] = uVal; pVBoxSCSI->iCDB++; /* Check if we have all necessary command data. */ if (pVBoxSCSI->iCDB == pVBoxSCSI->cbCDB) { Log(("%s: Command ready for processing\n", __FUNCTION__)); pVBoxSCSI->enmState = VBOXSCSISTATE_COMMAND_READY; if (pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_TO_DEVICE) { /* This is a write allocate buffer. */ pVBoxSCSI->pBuf = (uint8_t *)RTMemAllocZ(pVBoxSCSI->cbBuf); if (!pVBoxSCSI->pBuf) return VERR_NO_MEMORY; } else { /* This is a read from the device. */ ASMAtomicXchgBool(&pVBoxSCSI->fBusy, true); rc = VERR_MORE_DATA; /** @todo Better return value to indicate ready command? */ } } } else AssertMsgFailed(("Invalid state %d\n", pVBoxSCSI->enmState)); break; } case 1: { if ( pVBoxSCSI->enmState != VBOXSCSISTATE_COMMAND_READY || pVBoxSCSI->uTxDir != VBOXSCSI_TXDIR_TO_DEVICE) { /* Reset the state */ vboxscsiReset(pVBoxSCSI); } else { pVBoxSCSI->pBuf[pVBoxSCSI->iBuf++] = uVal; if (pVBoxSCSI->iBuf == pVBoxSCSI->cbBuf) { rc = VERR_MORE_DATA; ASMAtomicXchgBool(&pVBoxSCSI->fBusy, true); } } break; } case 2: { pVBoxSCSI->regIdentify = uVal; break; } case 3: { /* Reset */ vboxscsiReset(pVBoxSCSI); break; } default: AssertMsgFailed(("Invalid register to write to %u\n", iRegister)); } return rc; }
/* Functions */ void amqp_plugin(int pipe_fd, struct configuration *cfgptr, void *ptr) { struct pkt_data *data; struct ports_table pt; unsigned char *pipebuf; struct pollfd pfd; struct insert_data idata; time_t t; int timeout, refresh_timeout, amqp_timeout, ret, num; struct ring *rg = &((struct channels_list_entry *)ptr)->rg; struct ch_status *status = ((struct channels_list_entry *)ptr)->status; struct plugins_list_entry *plugin_data = ((struct channels_list_entry *)ptr)->plugin; int datasize = ((struct channels_list_entry *)ptr)->datasize; u_int32_t bufsz = ((struct channels_list_entry *)ptr)->bufsize; pid_t core_pid = ((struct channels_list_entry *)ptr)->core_pid; struct networks_file_data nfd; unsigned char *rgptr; int pollagain = TRUE; u_int32_t seq = 1, rg_err_count = 0; struct extra_primitives extras; struct primitives_ptrs prim_ptrs; char *dataptr; struct p_amqp_host *amqp_host = &((struct channels_list_entry *)ptr)->amqp_host; memcpy(&config, cfgptr, sizeof(struct configuration)); memcpy(&extras, &((struct channels_list_entry *)ptr)->extras, sizeof(struct extra_primitives)); recollect_pipe_memory(ptr); pm_setproctitle("%s [%s]", "RabbitMQ/AMQP Plugin", config.name); P_set_signals(); P_init_default_values(); P_config_checks(); pipebuf = (unsigned char *) pm_malloc(config.buffer_size); memset(pipebuf, 0, config.buffer_size); timeout = config.sql_refresh_time*1000; if (!config.sql_user) config.sql_user = rabbitmq_user; if (!config.sql_passwd) config.sql_passwd = rabbitmq_pwd; if ((config.sql_table && strchr(config.sql_table, '$')) && config.sql_multi_values) { Log(LOG_ERR, "ERROR ( %s/%s ): dynamic 'amqp_routing_key' is not compatible with 'amqp_multi_values'. Exiting.\n", config.name, config.type); exit_plugin(1); } if ((config.sql_table && strchr(config.sql_table, '$')) && config.amqp_routing_key_rr) { Log(LOG_ERR, "ERROR ( %s/%s ): dynamic 'amqp_routing_key' is not compatible with 'amqp_routing_key_rr'. Exiting.\n", config.name, config.type); exit_plugin(1); } p_amqp_init_host(&amqpp_amqp_host); p_amqp_set_user(&amqpp_amqp_host, config.sql_user); p_amqp_set_passwd(&amqpp_amqp_host, config.sql_passwd); /* setting function pointers */ if (config.what_to_count & (COUNT_SUM_HOST|COUNT_SUM_NET)) insert_func = P_sum_host_insert; else if (config.what_to_count & COUNT_SUM_PORT) insert_func = P_sum_port_insert; else if (config.what_to_count & COUNT_SUM_AS) insert_func = P_sum_as_insert; #if defined (HAVE_L2) else if (config.what_to_count & COUNT_SUM_MAC) insert_func = P_sum_mac_insert; #endif else insert_func = P_cache_insert; purge_func = amqp_cache_purge; memset(&nt, 0, sizeof(nt)); memset(&nc, 0, sizeof(nc)); memset(&pt, 0, sizeof(pt)); load_networks(config.networks_file, &nt, &nc); set_net_funcs(&nt); if (config.ports_file) load_ports(config.ports_file, &pt); if (config.pkt_len_distrib_bins_str) load_pkt_len_distrib_bins(); else { if (config.what_to_count_2 & COUNT_PKT_LEN_DISTRIB) { Log(LOG_ERR, "ERROR ( %s/%s ): 'aggregate' contains pkt_len_distrib but no 'pkt_len_distrib_bins' defined. Exiting.\n", config.name, config.type); exit_plugin(1); } } memset(&idata, 0, sizeof(idata)); memset(&prim_ptrs, 0, sizeof(prim_ptrs)); set_primptrs_funcs(&extras); if (config.pipe_amqp) { plugin_pipe_amqp_compile_check(); pipe_fd = plugin_pipe_amqp_connect_to_consume(amqp_host, plugin_data); amqp_timeout = plugin_pipe_set_retry_timeout(&amqp_host->btimers, pipe_fd); } else setnonblocking(pipe_fd); idata.now = time(NULL); /* print_refresh time init: deadline */ refresh_deadline = idata.now; P_init_refresh_deadline(&refresh_deadline); if (config.sql_history) { basetime_init = P_init_historical_acct; basetime_eval = P_eval_historical_acct; basetime_cmp = P_cmp_historical_acct; (*basetime_init)(idata.now); } /* setting number of entries in _protocols structure */ while (_protocols[protocols_number].number != -1) protocols_number++; /* plugin main loop */ for(;;) { poll_again: status->wakeup = TRUE; calc_refresh_timeout(refresh_deadline, idata.now, &refresh_timeout); pfd.fd = pipe_fd; pfd.events = POLLIN; timeout = MIN(refresh_timeout, (amqp_timeout ? amqp_timeout : INT_MAX)); ret = poll(&pfd, (pfd.fd == ERR ? 0 : 1), timeout); if (ret <= 0) { if (getppid() == 1) { Log(LOG_ERR, "ERROR ( %s/%s ): Core process *seems* gone. Exiting.\n", config.name, config.type); exit_plugin(1); } if (ret < 0) goto poll_again; } idata.now = time(NULL); if (config.sql_history) { while (idata.now > (basetime.tv_sec + timeslot)) { new_basetime.tv_sec = basetime.tv_sec; basetime.tv_sec += timeslot; if (config.sql_history == COUNT_MONTHLY) timeslot = calc_monthly_timeslot(basetime.tv_sec, config.sql_history_howmany, ADD); } } if (config.pipe_amqp && pipe_fd == ERR) { if (timeout == amqp_timeout) { pipe_fd = plugin_pipe_amqp_connect_to_consume(amqp_host, plugin_data); amqp_timeout = plugin_pipe_set_retry_timeout(&amqp_host->btimers, pipe_fd); } else amqp_timeout = plugin_pipe_calc_retry_timeout_diff(&amqp_host->btimers, idata.now); } switch (ret) { case 0: /* timeout */ P_cache_handle_flush_event(&pt); break; default: /* we received data */ read_data: if (!config.pipe_amqp) { if (!pollagain) { seq++; seq %= MAX_SEQNUM; if (seq == 0) rg_err_count = FALSE; } else { if ((ret = read(pipe_fd, &rgptr, sizeof(rgptr))) == 0) exit_plugin(1); /* we exit silently; something happened at the write end */ } if ((rg->ptr + bufsz) > rg->end) rg->ptr = rg->base; if (((struct ch_buf_hdr *)rg->ptr)->seq != seq) { if (!pollagain) { pollagain = TRUE; goto poll_again; } else { rg_err_count++; if (config.debug || (rg_err_count > MAX_RG_COUNT_ERR)) { Log(LOG_ERR, "ERROR ( %s/%s ): We are missing data.\n", config.name, config.type); Log(LOG_ERR, "If you see this message once in a while, discard it. Otherwise some solutions follow:\n"); Log(LOG_ERR, "- increase shared memory size, 'plugin_pipe_size'; now: '%u'.\n", config.pipe_size); Log(LOG_ERR, "- increase buffer size, 'plugin_buffer_size'; now: '%u'.\n", config.buffer_size); Log(LOG_ERR, "- increase system maximum socket size.\n\n"); } seq = ((struct ch_buf_hdr *)rg->ptr)->seq; } } pollagain = FALSE; memcpy(pipebuf, rg->ptr, bufsz); rg->ptr += bufsz; } else { ret = p_amqp_consume_binary(amqp_host, pipebuf, config.buffer_size); if (ret) pipe_fd = ERR; seq = ((struct ch_buf_hdr *)pipebuf)->seq; amqp_timeout = plugin_pipe_set_retry_timeout(&amqp_host->btimers, pipe_fd); } /* lazy refresh time handling */ if (idata.now > refresh_deadline) P_cache_handle_flush_event(&pt); data = (struct pkt_data *) (pipebuf+sizeof(struct ch_buf_hdr)); if (config.debug_internal_msg) Log(LOG_DEBUG, "DEBUG ( %s/%s ): buffer received cpid=%u seq=%u num_entries=%u\n", config.name, config.type, core_pid, seq, ((struct ch_buf_hdr *)pipebuf)->num); if (!config.pipe_check_core_pid || ((struct ch_buf_hdr *)pipebuf)->core_pid == core_pid) { while (((struct ch_buf_hdr *)pipebuf)->num > 0) { for (num = 0; primptrs_funcs[num]; num++) (*primptrs_funcs[num])((u_char *)data, &extras, &prim_ptrs); for (num = 0; net_funcs[num]; num++) (*net_funcs[num])(&nt, &nc, &data->primitives, prim_ptrs.pbgp, &nfd); if (config.ports_file) { if (!pt.table[data->primitives.src_port]) data->primitives.src_port = 0; if (!pt.table[data->primitives.dst_port]) data->primitives.dst_port = 0; } if (config.pkt_len_distrib_bins_str && config.what_to_count_2 & COUNT_PKT_LEN_DISTRIB) evaluate_pkt_len_distrib(data); prim_ptrs.data = data; (*insert_func)(&prim_ptrs, &idata); ((struct ch_buf_hdr *)pipebuf)->num--; if (((struct ch_buf_hdr *)pipebuf)->num) { dataptr = (unsigned char *) data; if (!prim_ptrs.vlen_next_off) dataptr += datasize; else dataptr += prim_ptrs.vlen_next_off; data = (struct pkt_data *) dataptr; } } } if (!config.pipe_amqp) goto read_data; } } }
static Mustache NextTag(const char *input, const char *delim_start, size_t delim_start_len, const char *delim_end, size_t delim_end_len) { Mustache ret; ret.type = TAG_TYPE_NONE; ret.begin = strstr(input, delim_start); if (!ret.begin) { return ret; } ret.content = ret.begin + delim_start_len; char *extra_end = NULL; switch (ret.content[0]) { case '#': ret.type = TAG_TYPE_SECTION; ret.content++; break; case '^': ret.type = TAG_TYPE_INVERTED; ret.content++; break; case '/': ret.type = TAG_TYPE_SECTION_END; ret.content++; break; case '!': ret.type = TAG_TYPE_COMMENT; ret.content++; break; case '=': extra_end = "="; ret.type = TAG_TYPE_DELIM; ret.content++; break; case '{': extra_end = "}"; case '&': ret.type = TAG_TYPE_VAR_UNESCAPED; ret.content++; break; default: ret.type = TAG_TYPE_VAR; break; } if (extra_end) { const char *escape_end = strstr(ret.content, extra_end); if (!escape_end || strncmp(escape_end + 1, delim_end, delim_end_len) != 0) { Log(LOG_LEVEL_WARNING, "Broken mustache template, couldn't find end tag for quoted begin tag at '%20s'...", input); ret.type = TAG_TYPE_ERR; return ret; } ret.content_len = escape_end - ret.content; ret.end = escape_end + 1 + delim_end_len; } else { ret.end = strstr(ret.content, delim_end); if (!ret.end) { Log(LOG_LEVEL_WARNING, "Broken Mustache template, could not find end delimiter after reading start delimiter at '%20s'...", input); ret.type = TAG_TYPE_ERR; return ret; } ret.content_len = ret.end - ret.content; ret.end += delim_end_len; } while (*ret.content == ' ' || *ret.content == '\t') { ret.content++; ret.content_len--; } while (ret.content[ret.content_len - 1] == ' ' || ret.content[ret.content_len - 1] == '\t') { ret.content_len--; } return ret; }
void amqp_cache_purge(struct chained_cache *queue[], int index) { struct pkt_primitives *data = NULL; struct pkt_bgp_primitives *pbgp = NULL; struct pkt_nat_primitives *pnat = NULL; struct pkt_mpls_primitives *pmpls = NULL; char *pcust = NULL; struct pkt_vlen_hdr_primitives *pvlen = NULL; struct pkt_bgp_primitives empty_pbgp; struct pkt_nat_primitives empty_pnat; struct pkt_mpls_primitives empty_pmpls; char *empty_pcust = NULL; char src_mac[18], dst_mac[18], src_host[INET6_ADDRSTRLEN], dst_host[INET6_ADDRSTRLEN], ip_address[INET6_ADDRSTRLEN]; char rd_str[SRVBUFLEN], misc_str[SRVBUFLEN], dyn_amqp_routing_key[SRVBUFLEN], *orig_amqp_routing_key = NULL; int i, j, stop, batch_idx, is_routing_key_dyn = FALSE, qn = 0, ret, saved_index = index; int mv_num = 0, mv_num_save = 0; time_t start, duration; pid_t writer_pid = getpid(); #ifdef WITH_JANSSON json_t *array = json_array(); #endif /* setting some defaults */ if (!config.sql_host) config.sql_host = default_amqp_host; if (!config.sql_db) config.sql_db = default_amqp_exchange; if (!config.amqp_exchange_type) config.amqp_exchange_type = default_amqp_exchange_type; if (!config.amqp_vhost) config.amqp_vhost = default_amqp_vhost; if (!config.sql_table) config.sql_table = default_amqp_routing_key; else { if (strchr(config.sql_table, '$')) { is_routing_key_dyn = TRUE; orig_amqp_routing_key = config.sql_table; config.sql_table = dyn_amqp_routing_key; } } if (config.amqp_routing_key_rr) { orig_amqp_routing_key = config.sql_table; config.sql_table = dyn_amqp_routing_key; } p_amqp_set_exchange(&amqpp_amqp_host, config.sql_db); p_amqp_set_routing_key(&amqpp_amqp_host, config.sql_table); p_amqp_set_exchange_type(&amqpp_amqp_host, config.amqp_exchange_type); p_amqp_set_host(&amqpp_amqp_host, config.sql_host); p_amqp_set_vhost(&amqpp_amqp_host, config.amqp_vhost); p_amqp_set_persistent_msg(&amqpp_amqp_host, config.amqp_persistent_msg); p_amqp_set_frame_max(&amqpp_amqp_host, config.amqp_frame_max); p_amqp_set_content_type_json(&amqpp_amqp_host); p_amqp_init_routing_key_rr(&amqpp_amqp_host); p_amqp_set_routing_key_rr(&amqpp_amqp_host, config.amqp_routing_key_rr); empty_pcust = malloc(config.cpptrs.len); if (!empty_pcust) { Log(LOG_ERR, "ERROR ( %s/%s ): Unable to malloc() empty_pcust. Exiting.\n", config.name, config.type); exit_plugin(1); } memset(&empty_pbgp, 0, sizeof(struct pkt_bgp_primitives)); memset(&empty_pnat, 0, sizeof(struct pkt_nat_primitives)); memset(&empty_pmpls, 0, sizeof(struct pkt_mpls_primitives)); memset(empty_pcust, 0, config.cpptrs.len); ret = p_amqp_connect_to_publish(&amqpp_amqp_host); if (ret) return; for (j = 0, stop = 0; (!stop) && P_preprocess_funcs[j]; j++) stop = P_preprocess_funcs[j](queue, &index, j); Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - START (PID: %u) ***\n", config.name, config.type, writer_pid); start = time(NULL); for (j = 0; j < index; j++) { void *json_obj; char *json_str; if (queue[j]->valid != PRINT_CACHE_COMMITTED) continue; data = &queue[j]->primitives; if (queue[j]->pbgp) pbgp = queue[j]->pbgp; else pbgp = &empty_pbgp; if (queue[j]->pnat) pnat = queue[j]->pnat; else pnat = &empty_pnat; if (queue[j]->pmpls) pmpls = queue[j]->pmpls; else pmpls = &empty_pmpls; if (queue[j]->pcust) pcust = queue[j]->pcust; else pcust = empty_pcust; if (queue[j]->pvlen) pvlen = queue[j]->pvlen; else pvlen = NULL; if (queue[j]->valid == PRINT_CACHE_FREE) continue; json_obj = compose_json(config.what_to_count, config.what_to_count_2, queue[j]->flow_type, &queue[j]->primitives, pbgp, pnat, pmpls, pcust, pvlen, queue[j]->bytes_counter, queue[j]->packet_counter, queue[j]->flow_counter, queue[j]->tcp_flags, &queue[j]->basetime, queue[j]->stitch); json_str = compose_json_str(json_obj); #ifdef WITH_JANSSON if (json_str && config.sql_multi_values) { json_t *elem = NULL; char *tmp_str = json_str; int do_free = FALSE; if (json_array_size(array) >= config.sql_multi_values) { json_str = json_dumps(array, 0); json_array_clear(array); mv_num_save = mv_num; mv_num = 0; } else do_free = TRUE; elem = json_loads(tmp_str, 0, NULL); json_array_append_new(array, elem); mv_num++; if (do_free) { free(json_str); json_str = NULL; } } #endif if (json_str) { if (is_routing_key_dyn) { P_handle_table_dyn_strings(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, queue[j]); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } if (config.amqp_routing_key_rr) { P_handle_table_dyn_rr(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, &amqpp_amqp_host.rk_rr); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } ret = p_amqp_publish_string(&amqpp_amqp_host, json_str); free(json_str); json_str = NULL; if (!ret) { if (!config.sql_multi_values) qn++; else qn += mv_num_save; } else break; } } #ifdef WITH_JANSSON if (config.sql_multi_values && json_array_size(array)) { char *json_str; json_str = json_dumps(array, 0); json_array_clear(array); json_decref(array); if (json_str) { /* no handling of dyn routing keys here: not compatible */ ret = p_amqp_publish_string(&amqpp_amqp_host, json_str); free(json_str); json_str = NULL; if (!ret) qn += mv_num; } } #endif p_amqp_close(&amqpp_amqp_host, FALSE); duration = time(NULL)-start; Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - END (PID: %u, QN: %u/%u, ET: %u) ***\n", config.name, config.type, writer_pid, qn, saved_index, duration); if (config.sql_trigger_exec) P_trigger_exec(config.sql_trigger_exec); if (empty_pcust) free(empty_pcust); }
int SelectLeaf(EvalContext *ctx, char *path, struct stat *sb, FileSelect fs) { Rlist *rp; StringSet *leaf_attr = StringSetNew(); #ifdef __MINGW32__ if (fs.issymlinkto != NULL) { Log(LOG_LEVEL_VERBOSE, "files_select.issymlinkto is ignored on Windows (symbolic links are not supported by Windows)"); } if (fs.groups != NULL) { Log(LOG_LEVEL_VERBOSE, "files_select.search_groups is ignored on Windows (file groups are not supported by Windows)"); } if (fs.bsdflags != NULL) { Log(LOG_LEVEL_VERBOSE, "files_select.search_bsdflags is ignored on Windows"); } #endif /* __MINGW32__ */ if (fs.name == NULL) { StringSetAdd(leaf_attr, xstrdup("leaf_name")); } for (rp = fs.name; rp != NULL; rp = rp->next) { if (SelectNameRegexMatch(ctx, path, RlistScalarValue(rp))) { StringSetAdd(leaf_attr, xstrdup("leaf_name")); break; } } if (fs.path == NULL) { StringSetAdd(leaf_attr, xstrdup("leaf_path")); } for (rp = fs.path; rp != NULL; rp = rp->next) { if (SelectPathRegexMatch(ctx, path, RlistScalarValue(rp))) { StringSetAdd(leaf_attr, xstrdup("path_name")); break; } } if (SelectTypeMatch(sb, fs.filetypes)) { StringSetAdd(leaf_attr, xstrdup("file_types")); } if ((fs.owners) && (SelectOwnerMatch(ctx, path, sb, fs.owners))) { StringSetAdd(leaf_attr, xstrdup("owner")); } if (fs.owners == NULL) { StringSetAdd(leaf_attr, xstrdup("owner")); } #ifdef __MINGW32__ StringSetAdd(leaf_attr, xstrdup("group")); #else /* !__MINGW32__ */ if ((fs.groups) && (SelectGroupMatch(ctx, sb, fs.groups))) { StringSetAdd(leaf_attr, xstrdup("group")); } if (fs.groups == NULL) { StringSetAdd(leaf_attr, xstrdup("group")); } #endif /* !__MINGW32__ */ if (SelectModeMatch(sb, fs.perms)) { StringSetAdd(leaf_attr, xstrdup("mode")); } #if defined HAVE_CHFLAGS if (SelectBSDMatch(sb, fs.bsdflags)) { StringSetAdd(leaf_attr, xstrdup("bsdflags")); } #endif if (SelectTimeMatch(sb->st_atime, fs.min_atime, fs.max_atime)) { StringSetAdd(leaf_attr, xstrdup("atime")); } if (SelectTimeMatch(sb->st_ctime, fs.min_ctime, fs.max_ctime)) { StringSetAdd(leaf_attr, xstrdup("ctime")); } if (SelectSizeMatch(sb->st_size, fs.min_size, fs.max_size)) { StringSetAdd(leaf_attr, xstrdup("size")); } if (SelectTimeMatch(sb->st_mtime, fs.min_mtime, fs.max_mtime)) { StringSetAdd(leaf_attr, xstrdup("mtime")); } if ((fs.issymlinkto) && (SelectIsSymLinkTo(ctx, path, fs.issymlinkto))) { StringSetAdd(leaf_attr, xstrdup("issymlinkto")); } if ((fs.exec_regex) && (SelectExecRegexMatch(ctx, path, fs.exec_regex, fs.exec_program))) { StringSetAdd(leaf_attr, xstrdup("exec_regex")); } if ((fs.exec_program) && (SelectExecProgram(path, fs.exec_program))) { StringSetAdd(leaf_attr, xstrdup("exec_program")); } bool result = EvalFileResult(fs.result, leaf_attr); Log(LOG_LEVEL_VERBOSE, "file_select result '%s' on '%s' was '%s'", fs.result, path, result ? "true" : "false"); StringSetDestroy(leaf_attr); return result; }
int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options) { MQTTClients* m = handle; int rc = SOCKET_ERROR; START_TIME_TYPE start; long millisecsTimeout = 30000L; FUNC_ENTRY; Thread_lock_mutex(mqttclient_mutex); if (options == NULL) { rc = MQTTCLIENT_NULL_PARAMETER; goto exit; } if (strncmp(options->struct_id, "MQTC", 4) != 0 || (options->struct_version != 0 && options->struct_version != 1)) { rc = MQTTCLIENT_BAD_STRUCTURE; goto exit; } if (options->will) /* check validity of will options structure */ { if (strncmp(options->will->struct_id, "MQTW", 4) != 0 || options->will->struct_version != 0) { rc = MQTTCLIENT_BAD_STRUCTURE; goto exit; } } #if defined(OPENSSL) if (options->struct_version != 0 && options->ssl) /* check validity of SSL options structure */ { if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version != 0) { rc = MQTTCLIENT_BAD_STRUCTURE; goto exit; } } #endif if ((options->username && !UTF8_validateString(options->username)) || (options->password && !UTF8_validateString(options->password))) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } millisecsTimeout = options->connectTimeout * 1000; start = MQTTClient_start_clock(); if (m->ma && !running) { Thread_start(MQTTClient_run, handle); if (MQTTClient_elapsed(start) >= millisecsTimeout) { rc = SOCKET_ERROR; goto exit; } MQTTClient_sleep(100L); } m->c->keepAliveInterval = options->keepAliveInterval; m->c->cleansession = options->cleansession; m->c->maxInflightMessages = (options->reliable) ? 1 : 10; if (options->will && options->will->struct_version == 0) { m->c->will = malloc(sizeof(willMessages)); m->c->will->msg = options->will->message; m->c->will->qos = options->will->qos; m->c->will->retained = options->will->retained; m->c->will->topic = options->will->topicName; } #if defined(OPENSSL) if (options->struct_version != 0 && options->ssl) m->c->sslopts = options->ssl; #endif m->c->username = options->username; m->c->password = options->password; m->c->retryInterval = options->retryInterval; Log(TRACE_MIN, -1, "Connecting to serverURI %s", m->serverURI); #if defined(OPENSSL) rc = MQTTProtocol_connect(m->serverURI, m->c, m->ssl); #else rc = MQTTProtocol_connect(m->serverURI, m->c); #endif if (rc == SOCKET_ERROR) goto exit; if (m->c->connect_state == 0) { rc = SOCKET_ERROR; goto exit; } if (m->c->connect_state == 1) /* TCP connect started - wait for completion */ { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_waitfor(handle, CONNECT, &rc, millisecsTimeout - MQTTClient_elapsed(start)); Thread_lock_mutex(mqttclient_mutex); if (rc != 0) { rc = SOCKET_ERROR; goto exit; } #if defined(OPENSSL) if (m->ssl) { if (SSLSocket_setSocketForSSL(&m->c->net, m->c->sslopts) != MQTTCLIENT_SUCCESS) { if (m->c->session != NULL) if ((rc = SSL_set_session(m->c->net.ssl, m->c->session)) != 1) Log(TRACE_MIN, -1, "Failed to set SSL session with stored data, non critical"); rc = SSLSocket_connect(m->c->net.ssl, m->c->net.socket); if (rc == -1) m->c->connect_state = 2; else if (rc == SSL_FATAL) { rc = SOCKET_ERROR; goto exit; } else if (rc == 1 && !m->c->cleansession && m->c->session == NULL) m->c->session = SSL_get1_session(m->c->net.ssl); } else { rc = SOCKET_ERROR; goto exit; } } else { #endif m->c->connect_state = 3; /* TCP connect completed, in which case send the MQTT connect packet */ if (MQTTPacket_send_connect(m->c) == SOCKET_ERROR) { rc = SOCKET_ERROR; goto exit; } #if defined(OPENSSL) } #endif } #if defined(OPENSSL) if (m->c->connect_state == 2) /* SSL connect sent - wait for completion */ { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_waitfor(handle, CONNECT, &rc, millisecsTimeout - MQTTClient_elapsed(start)); Thread_lock_mutex(mqttclient_mutex); if (rc != 1) { rc = SOCKET_ERROR; goto exit; } m->c->connect_state = 3; /* TCP connect completed, in which case send the MQTT connect packet */ if (MQTTPacket_send_connect(m->c) == SOCKET_ERROR) { rc = SOCKET_ERROR; goto exit; } } #endif if (m->c->connect_state == 3) /* MQTT connect sent - wait for CONNACK */ { MQTTPacket* pack = NULL; Thread_unlock_mutex(mqttclient_mutex); pack = MQTTClient_waitfor(handle, CONNACK, &rc, millisecsTimeout - MQTTClient_elapsed(start)); Thread_lock_mutex(mqttclient_mutex); if (pack == NULL) rc = SOCKET_ERROR; else { Connack* connack = (Connack*)pack; Log(LOG_PROTOCOL, 1, NULL, m->c->net.socket, m->c->clientID, connack->rc); if ((rc = connack->rc) == MQTTCLIENT_SUCCESS) { m->c->connected = 1; m->c->good = 1; m->c->connect_state = 0; if (m->c->cleansession) rc = MQTTClient_cleanSession(m->c); if (m->c->outboundMsgs->count > 0) { ListElement* outcurrent = NULL; while (ListNextElement(m->c->outboundMsgs, &outcurrent)) { Messages* m = (Messages*)(outcurrent->content); m->lastTouch = 0; } MQTTProtocol_retry(m->c->net.lastContact, 1); if (m->c->connected != 1) rc = MQTTCLIENT_DISCONNECTED; } } free(connack); m->pack = NULL; } } exit: if (rc != MQTTCLIENT_SUCCESS) { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_disconnect(handle, 0); /* not "internal" because we don't want to call connection lost */ Thread_lock_mutex(mqttclient_mutex); } if (m->c->will) { free(m->c->will); m->c->will = NULL; } Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
int ClientSocket::Connect(const std::string &addr, int port, bool block) throw (utils::Exception) { if (IsConnected()) { Log("Socket is already connected : %d", m_Fd); throw utils::Exception("Socket is already connected"); } Log("connect to %s:%d", addr.c_str(), port); char strPort[10] = { 0 }; sprintf(strPort, "%d", port); // Tell the system what kind(s) of address info we want struct addrinfo addrCriteria; // Criteria for address match memset(&addrCriteria, 0, sizeof(addrCriteria)); // Zero out structure addrCriteria.ai_family = AF_UNSPEC; // v4 or v6 is OK addrCriteria.ai_socktype = SOCK_STREAM; // Only streaming sockets addrCriteria.ai_protocol = IPPROTO_TCP; // Only TCP protocol // Get address(es) struct addrinfo *servAddr; // Holder for returned list of server addrs const char* pAddr = addr.size() > 0 ? addr.data() : NULL; int rtnVal = getaddrinfo(pAddr, strPort, &addrCriteria, &servAddr); if (rtnVal != 0 || servAddr == NULL) { Log("getaddrinfo failed, addr=%s:%d, error=%d:%s", pAddr, port, errno, strerror(errno)); return 0 - errno; } int fd = -1; int err = 0; struct addrinfo *addr_info; int nodelay = 1; int keepalive = 1; for (addr_info = servAddr; addr_info != NULL; addr_info = addr_info->ai_next) { // Create a reliable, stream socket using TCP fd = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol); if (fd < 0) { err = errno; continue; // Socket creation failed; try next address } else if ((setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay))) < 0) { Log("nodelay %d failed, errer = %d:%s", fd, errno, strerror(errno)); err = errno; } else if ((setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive))) < 0) { Log("keepalive %d failed, errer = %d:%s", fd, errno, strerror(errno)); err = errno; } else if (::connect(fd, addr_info->ai_addr, addr_info->ai_addrlen) < 0) { // Establish the connection to the echo server err = errno; Log("connect %d failed, error=%d:%s", fd, errno, strerror(errno)); } else { err = 0; break; } close(fd); // Socket connection failed; try next address fd = -1; } freeaddrinfo(servAddr); // Free addrinfo allocated in getaddrinfo() if (fd <= 0) { Log("connect failed to %s:%d, error=%d:%s", pAddr, port, err, strerror(err)); return -1; } m_Fd = fd; if (!block) { int flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); } return fd; }
//----------------------------------------------------------------------------- bool HoneDumpcap::CapturePackets(void) { while (m_captureState != CaptureStateDone) { #ifdef WIN32 if (m_signalPipeHandle != InvalidFileHandle) { DWORD bytesAvailable; const BOOL rc = ::PeekNamedPipe(m_signalPipeHandle, NULL, 0, NULL, &bytesAvailable, NULL); if (!rc || (bytesAvailable > 0)) { Log(QString("Parent process %1 is closing us").arg(m_parentPid)); m_markCleanup = true; } } #else // #ifdef WIN32 fd_set readfds; #endif // #ifdef WIN32 if (m_markCleanup && (m_captureState != CaptureStateCleanUp)) { if (!MarkRestart()) { return false; } m_captureState = CaptureStateCleanUp; m_markCleanup = false; } if (m_markRotate && (m_captureState == CaptureStateNormal)) { if (!MarkRestart()) { return false; } m_captureState = CaptureStateRotate; m_markRotate = false; } quint32 bytesRead; if (!ReadDriver(bytesRead)) { return false; } if (bytesRead) { const qint32 packetCount = CountPackets(bytesRead); const qint64 bytesWritten = m_captureFile.write(m_captureData.data(), bytesRead); if (bytesWritten == -1) { return LogError(QString("Cannot write %L1 bytes to %2: %3").arg(bytesRead) .arg(m_captureFile.fileName(), m_captureFile.errorString())); } if (bytesRead != bytesWritten) { return LogError(QString("Only wrote %L1 of %L2 bytes to %3").arg(bytesWritten).arg(bytesRead) .arg(m_captureFile.fileName())); } if (!m_captureFile.flush()) { return LogError(QString("Cannot flush %1: %2").arg(m_captureFile.fileName(),m_captureFile.errorString())); } m_captureFileSize += bytesWritten; m_packetCount += packetCount; if (m_parentPid.isEmpty()) { Log(QString("\rPackets: %1").arg(m_packetCount), false); } else { WriteCommand('P', QString::number(packetCount)); } // Handle stop and rotate conditions if ( (m_autoStopFileCount && (m_captureFileCount >= m_autoStopFileCount )) || (m_autoStopFileSize && (m_captureFileSize >= m_autoStopFileSize )) || (m_autoStopPacketCount && (m_packetCount >= m_autoStopPacketCount)) || (m_autoStopMilliseconds && ((QDateTime::currentMSecsSinceEpoch() - m_captureStart) > m_autoStopMilliseconds))) { m_markCleanup = true; } else if ( (m_autoRotateFileSize && (m_captureFileSize >= m_autoRotateFileSize)) || (m_autoRotateMilliseconds && ((QDateTime::currentMSecsSinceEpoch() - m_captureStart) > m_autoRotateMilliseconds))) { m_markRotate = true; } } else { // No data to read switch (m_captureState) { case CaptureStateCleanUp: #ifndef WIN32 if (::ioctl(m_driverHandle, HEIO_GET_AT_HEAD) <= 0) { break; } #endif // #ifdef WIN32 m_captureState = CaptureStateDone; break; case CaptureStateDone: break; case CaptureStateNormal: #ifdef WIN32 ::Sleep(500); #else // #ifdef WIN32 FD_ZERO(&readfds); FD_SET(m_driverHandle, &readfds); if (-1 == ::select(m_driverHandle+1, &readfds, NULL, NULL, NULL)) { if (errno == EINTR) { m_markCleanup = true; } else { return LogError("Cannot check for data from the driver", true); } } #endif // #ifdef WIN32 break; case CaptureStateRotate: #ifndef WIN32 if (::ioctl(m_driverHandle, HEIO_GET_AT_HEAD) <= 0) { break; } #endif // #ifdef WIN32 if (!OpenCaptureFile()) { return false; } m_captureState = CaptureStateNormal; break; } } } return true; }
/** * Saves the current save. */ void SaveGameState::think() { State::think(); // Make sure it gets drawn properly if (_firstRun < 10) { _firstRun++; } else { _game->popState(); switch (_type) { case SAVE_DEFAULT: // manual save, close the save screen _game->popState(); if (!_game->getSavedGame()->isIronman()) { // and pause screen too _game->popState(); } break; case SAVE_QUICK: case SAVE_AUTO_GEOSCAPE: case SAVE_AUTO_BATTLESCAPE: // automatic save, give it a default name _game->getSavedGame()->setName(Language::fsToWstr(_filename)); default: break; } // Save the game try { std::string backup = _filename + ".bak"; _game->getSavedGame()->save(backup); std::string fullPath = Options::getMasterUserFolder() + _filename; std::string bakPath = Options::getMasterUserFolder() + backup; if (!CrossPlatform::moveFile(bakPath, fullPath)) { throw Exception("Save backed up in " + backup); } if (_type == SAVE_IRONMAN_END) { Screen::updateScale(Options::geoscapeScale, Options::geoscapeScale, Options::baseXGeoscape, Options::baseYGeoscape, true); _game->getScreen()->resetDisplay(false); _game->setState(new MainMenuState); _game->setSavedGame(0); } } catch (Exception &e) { Log(LOG_ERROR) << e.what(); std::wostringstream error; error << tr("STR_SAVE_UNSUCCESSFUL") << L'\x02' << Language::fsToWstr(e.what()); if (_origin != OPT_BATTLESCAPE) _game->pushState(new ErrorMessageState(error.str(), _palette, _game->getMod()->getInterface("errorMessages")->getElement("geoscapeColor")->color, "BACK01.SCR", _game->getMod()->getInterface("errorMessages")->getElement("geoscapePalette")->color)); else _game->pushState(new ErrorMessageState(error.str(), _palette, _game->getMod()->getInterface("errorMessages")->getElement("battlescapeColor")->color, "TAC00.SCR", _game->getMod()->getInterface("errorMessages")->getElement("battlescapePalette")->color)); } catch (YAML::Exception &e) { Log(LOG_ERROR) << e.what(); std::wostringstream error; error << tr("STR_SAVE_UNSUCCESSFUL") << L'\x02' << Language::fsToWstr(e.what()); if (_origin != OPT_BATTLESCAPE) _game->pushState(new ErrorMessageState(error.str(), _palette, _game->getMod()->getInterface("errorMessages")->getElement("geoscapeColor")->color, "BACK01.SCR", _game->getMod()->getInterface("errorMessages")->getElement("geoscapePalette")->color)); else _game->pushState(new ErrorMessageState(error.str(), _palette, _game->getMod()->getInterface("errorMessages")->getElement("battlescapeColor")->color, "TAC00.SCR", _game->getMod()->getInterface("errorMessages")->getElement("battlescapePalette")->color)); } } }
BOOL CScanner::EnableDecoder(BYTE cDecoder) { BOOL bRetVal = FALSE; if (IsDecoderSupported(cDecoder)) { DECODER_LIST decoderList; DWORD dwResult; // Mark entire buffer allocated, and not used memset(&decoderList, 0, sizeof(DECODER_LIST)); SI_INIT(&decoderList); // Get enabled decoder list dwResult = lpfn_SCAN_GetEnabledDecoders(m_hScanner, &decoderList); if (dwResult == E_SCN_SUCCESS) { // Check we haven't already enabled the decoder for(DWORD i = 0; i < decoderList.Decoders.dwDecoderCount; i++) { if (decoderList.Decoders.byList[i] == cDecoder) { // The decoder is already enabled, alert the user and do nothing if (decoderStrings[cDecoder]) { WCHAR wLog[MAXLOG]; wsprintf(wLog, L"Attempted to enable the decoder %s but it is already enabled", decoderStrings[cDecoder]); Log(SCANNER_LOG_INFO, wLog, _T(__FUNCTION__), __LINE__); } return bRetVal; } } decoderList.Decoders.byList[decoderList.Decoders.dwDecoderCount++] = cDecoder; dwResult = lpfn_SCAN_SetEnabledDecoders(m_hScanner,&decoderList); if (dwResult != E_SCN_SUCCESS) { Log(SCANNER_LOG_WARNING, L"Unable to set Enabled Decoders", _T(__FUNCTION__), __LINE__); } else bRetVal = TRUE; } else { // Unable to retrieve the enabled decoders Log(SCANNER_LOG_WARNING, L"Unable to retrieve enabled decoders", _T(__FUNCTION__), __LINE__); } } else { // Attempted to enable an unsupported decoder WCHAR wLog[MAXLOG]; if (decoderStrings[cDecoder]) { wsprintf(wLog, L"Decoder %s is not supported on this device, unable to Enable it", decoderStrings[cDecoder]); Log(SCANNER_LOG_WARNING, wLog, _T(__FUNCTION__), __LINE__); } } return bRetVal; }
int SQLI_cache_dbop(struct DBdesc *db, struct db_cache *cache_elem, struct insert_data *idata) { char *ptr_values, *ptr_where, *ptr_mv, *ptr_set, *ptr_insert; int num=0, num_set=0, ret=0, have_flows=0, len=0; if (idata->mv.last_queue_elem) { ret = sqlite3_exec(db->desc, multi_values_buffer, NULL, NULL, NULL); Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d INSERT statements sent to the SQLite database.\n", config.name, config.type, idata->mv.buffer_elem_num); if (ret) goto signal_error; idata->iqn++; idata->mv.buffer_elem_num = FALSE; idata->mv.buffer_offset = 0; return FALSE; } if (config.what_to_count & COUNT_FLOWS) have_flows = TRUE; /* constructing sql query */ ptr_where = where_clause; ptr_values = values_clause; ptr_set = set_clause; ptr_insert = insert_full_clause; memset(where_clause, 0, sizeof(where_clause)); memset(values_clause, 0, sizeof(values_clause)); memset(set_clause, 0, sizeof(set_clause)); memset(insert_full_clause, 0, sizeof(insert_full_clause)); for (num = 0; num < idata->num_primitives; num++) (*where[num].handler)(cache_elem, idata, num, &ptr_values, &ptr_where); if (cache_elem->flow_type == NF9_FTYPE_EVENT || cache_elem->flow_type == NF9_FTYPE_OPTION) { for (num_set = 0; set_event[num_set].type; num_set++) (*set_event[num_set].handler)(cache_elem, idata, num_set, &ptr_set, NULL); } else { for (num_set = 0; set[num_set].type; num_set++) (*set[num_set].handler)(cache_elem, idata, num_set, &ptr_set, NULL); } /* sending UPDATE query a) if not switched off and b) if we actually have something to update */ if (!config.sql_dont_try_update && num_set) { strncpy(sql_data, update_clause, SPACELEFT(sql_data)); strncat(sql_data, set_clause, SPACELEFT(sql_data)); strncat(sql_data, where_clause, SPACELEFT(sql_data)); ret = sqlite3_exec(db->desc, sql_data, NULL, NULL, NULL); if (ret) goto signal_error; } if (config.sql_dont_try_update || !num_set || (sqlite3_changes(db->desc) == 0)) { /* UPDATE failed, trying with an INSERT query */ if (cache_elem->flow_type == NF9_FTYPE_EVENT || cache_elem->flow_type == NF9_FTYPE_OPTION) { strncpy(insert_full_clause, insert_clause, SPACELEFT(insert_full_clause)); strncat(insert_full_clause, insert_nocounters_clause, SPACELEFT(insert_full_clause)); strncat(ptr_values, ")", SPACELEFT(values_clause)); } else { strncpy(insert_full_clause, insert_clause, SPACELEFT(insert_full_clause)); strncat(insert_full_clause, insert_counters_clause, SPACELEFT(insert_full_clause)); #if defined HAVE_64BIT_COUNTERS if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter); #else if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter); #endif } strncpy(sql_data, insert_full_clause, sizeof(sql_data)); strncat(sql_data, values_clause, SPACELEFT(sql_data)); if (config.sql_multi_values) { multi_values_handling: len = config.sql_multi_values-idata->mv.buffer_offset; if (strlen(values_clause) < len) { if (idata->mv.buffer_elem_num) { strcpy(multi_values_buffer+idata->mv.buffer_offset, "; "); idata->mv.buffer_offset++; idata->mv.buffer_offset++; } ptr_mv = multi_values_buffer+idata->mv.buffer_offset; strcpy(multi_values_buffer+idata->mv.buffer_offset, sql_data); idata->mv.buffer_offset += strlen(ptr_mv); idata->mv.buffer_elem_num++; } else { if (idata->mv.buffer_elem_num) { ret = sqlite3_exec(db->desc, multi_values_buffer, NULL, NULL, NULL); Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d INSERT statements sent to the SQLite database.\n", config.name, config.type, idata->mv.buffer_elem_num); if (ret) goto signal_error; idata->iqn++; idata->mv.buffer_elem_num = FALSE; idata->mv.head_buffer_elem = FALSE; idata->mv.buffer_offset = 0; goto multi_values_handling; } else { Log(LOG_ERR, "ERROR ( %s/%s ): 'sql_multi_values' is too small (%d). Try with a larger value.\n", config.name, config.type, config.sql_multi_values); exit_plugin(1); } } } else { ret = sqlite3_exec(db->desc, sql_data, NULL, NULL, NULL); Log(LOG_DEBUG, "( %s/%s ): %s\n\n", config.name, config.type, sql_data); if (ret) goto signal_error; idata->iqn++; } } else { Log(LOG_DEBUG, "( %s/%s ): %s\n\n", config.name, config.type, sql_data); idata->uqn++; } idata->een++; // cache_elem->valid = FALSE; /* committed */ return ret; signal_error: if (!idata->mv.buffer_elem_num) Log(LOG_DEBUG, "DEBUG ( %s/%s ): FAILED query follows:\n%s\n", config.name, config.type, sql_data); else { if (!idata->recover || db->type != BE_TYPE_PRIMARY) { /* DB failure: we will rewind the multi-values buffer */ idata->current_queue_elem = idata->mv.head_buffer_elem; idata->mv.buffer_elem_num = 0; } } SQLI_get_errmsg(db); if (db->errmsg) Log(LOG_ERR, "ERROR ( %s/%s ): %s\n\n", config.name, config.type, db->errmsg); return ret; }
BOOL CScanner::DisableDecoder(BYTE cDecoder) { BOOL bRetVal = FALSE; if (IsDecoderSupported(cDecoder)) { DECODER_LIST decoderList; DWORD dwResult; // Mark entire buffer allocated, and not used memset(&decoderList, 0, sizeof(DECODER_LIST)); SI_INIT(&decoderList); bool bFoundDecoder = false; // Get enabled decoder list dwResult = lpfn_SCAN_GetEnabledDecoders(m_hScanner, &decoderList); if (dwResult == E_SCN_SUCCESS) { // Check we haven't already enabled the decoder for(DWORD i = 0; i < decoderList.Decoders.dwDecoderCount; i++) { if (decoderList.Decoders.byList[i] == cDecoder) { // The decoder is already enabled memcpy(decoderList.Decoders.byList + i, decoderList.Decoders.byList + (i + 1), decoderList.Decoders.dwDecoderCount - (i - 1)); decoderList.Decoders.dwDecoderCount--; bFoundDecoder = true; } } // Check the decoder was enabled if (!bFoundDecoder) { if (decoderStrings[cDecoder]) { WCHAR wLog[MAXLOG]; wsprintf(wLog, L"Decoder %s is not enabled, therefore unable to disable it", decoderStrings[cDecoder]); Log(SCANNER_LOG_INFO, wLog, _T(__FUNCTION__), __LINE__); } } else { // The decoder is enabled, disable it (decoderList updated earlier) dwResult = lpfn_SCAN_SetEnabledDecoders(m_hScanner, &decoderList); if (dwResult != E_SCN_SUCCESS) { Log(SCANNER_LOG_WARNING, L"Unable to set Enabled Decoders", _T(__FUNCTION__), __LINE__); } else bRetVal = TRUE; } } else { // Unable to retrieve the enabled decoders Log(SCANNER_LOG_WARNING, L"Unable to retrieve enabled decoders", _T(__FUNCTION__), __LINE__); } } else { // Attempted to disable an unsupported decoder if (decoderStrings[cDecoder]) { WCHAR wLog[MAXLOG]; wsprintf(wLog, L"Decoder %s is not supported on this device, unable to Disable it", decoderStrings[cDecoder]); Log(SCANNER_LOG_WARNING, wLog, _T(__FUNCTION__), __LINE__); } } return bRetVal; }
void SQLI_cache_purge(struct db_cache *queue[], int index, struct insert_data *idata) { struct db_cache *LastElemCommitted = NULL; time_t start; int j, stop, ret, go_to_pending, saved_index = index; char orig_insert_clause[LONGSRVBUFLEN], orig_update_clause[LONGSRVBUFLEN], orig_lock_clause[LONGSRVBUFLEN]; char tmpbuf[LONGLONGSRVBUFLEN], tmptable[SRVBUFLEN]; struct primitives_ptrs prim_ptrs; struct pkt_data dummy_data; pid_t writer_pid = getpid(); if (!index) { Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - START (PID: %u) ***\n", config.name, config.type, writer_pid); Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - END (PID: %u, QN: 0/0, ET: 0) ***\n", config.name, config.type, writer_pid); return; } memset(&prim_ptrs, 0, sizeof(prim_ptrs)); memset(&dummy_data, 0, sizeof(dummy_data)); for (j = 0, stop = 0; (!stop) && sql_preprocess_funcs[j]; j++) stop = sql_preprocess_funcs[j](queue, &index, j); if (config.what_to_count & COUNT_CLASS) sql_invalidate_shadow_entries(queue, &index); idata->ten = index; Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - START (PID: %u) ***\n", config.name, config.type, writer_pid); start = time(NULL); /* re-using pending queries queue stuff from parent and saving clauses */ memcpy(pending_queries_queue, queue, index*sizeof(struct db_cache *)); pqq_ptr = index; strlcpy(orig_insert_clause, insert_clause, LONGSRVBUFLEN); strlcpy(orig_update_clause, update_clause, LONGSRVBUFLEN); strlcpy(orig_lock_clause, lock_clause, LONGSRVBUFLEN); start: memset(&idata->mv, 0, sizeof(struct multi_values)); memcpy(queue, pending_queries_queue, pqq_ptr*sizeof(struct db_cache *)); memset(pending_queries_queue, 0, pqq_ptr*sizeof(struct db_cache *)); index = pqq_ptr; pqq_ptr = 0; /* We check for variable substitution in SQL table */ if (idata->dyn_table) { time_t stamp = 0; memset(tmpbuf, 0, LONGLONGSRVBUFLEN); stamp = queue[0]->basetime; prim_ptrs.data = &dummy_data; primptrs_set_all_from_db_cache(&prim_ptrs, queue[0]); strlcpy(idata->dyn_table_name, config.sql_table, SRVBUFLEN); strlcpy(insert_clause, orig_insert_clause, LONGSRVBUFLEN); strlcpy(update_clause, orig_update_clause, LONGSRVBUFLEN); strlcpy(lock_clause, orig_lock_clause, LONGSRVBUFLEN); handle_dynname_internal_strings_same(tmpbuf, LONGSRVBUFLEN, insert_clause, &prim_ptrs); handle_dynname_internal_strings_same(tmpbuf, LONGSRVBUFLEN, update_clause, &prim_ptrs); handle_dynname_internal_strings_same(tmpbuf, LONGSRVBUFLEN, lock_clause, &prim_ptrs); handle_dynname_internal_strings_same(tmpbuf, LONGSRVBUFLEN, idata->dyn_table_name, &prim_ptrs); strftime_same(insert_clause, LONGSRVBUFLEN, tmpbuf, &stamp); strftime_same(update_clause, LONGSRVBUFLEN, tmpbuf, &stamp); strftime_same(lock_clause, LONGSRVBUFLEN, tmpbuf, &stamp); strftime_same(idata->dyn_table_name, LONGSRVBUFLEN, tmpbuf, &stamp); if (config.sql_table_schema) sql_create_table(bed.p, &stamp, &prim_ptrs); } (*sqlfunc_cbr.lock)(bed.p); for (idata->current_queue_elem = 0; idata->current_queue_elem < index; idata->current_queue_elem++) { go_to_pending = FALSE; if (idata->dyn_table) { time_t stamp = 0; memset(tmpbuf, 0, LONGLONGSRVBUFLEN); // XXX: pedantic? stamp = queue[idata->current_queue_elem]->basetime; strlcpy(tmptable, config.sql_table, SRVBUFLEN); prim_ptrs.data = &dummy_data; primptrs_set_all_from_db_cache(&prim_ptrs, queue[idata->current_queue_elem]); handle_dynname_internal_strings_same(tmpbuf, LONGSRVBUFLEN, tmptable, &prim_ptrs); strftime_same(tmptable, LONGSRVBUFLEN, tmpbuf, &stamp); if (strncmp(idata->dyn_table_name, tmptable, SRVBUFLEN)) { pending_queries_queue[pqq_ptr] = queue[idata->current_queue_elem]; pqq_ptr++; go_to_pending = TRUE; } } if (!go_to_pending) { if (queue[idata->current_queue_elem]->valid) sql_query(&bed, queue[idata->current_queue_elem], idata); if (queue[idata->current_queue_elem]->valid == SQL_CACHE_COMMITTED) LastElemCommitted = queue[idata->current_queue_elem]; } } /* multi-value INSERT query: wrap-up */ if (idata->mv.buffer_elem_num) { idata->mv.last_queue_elem = TRUE; sql_query(&bed, LastElemCommitted, idata); idata->qn--; /* increased by sql_query() one time too much */ } /* rewinding stuff */ (*sqlfunc_cbr.unlock)(&bed); if (b.fail) Log(LOG_ALERT, "ALERT ( %s/%s ): recovery for SQLite3 daemon failed.\n", config.name, config.type); /* If we have pending queries then start again */ if (pqq_ptr) goto start; idata->elap_time = time(NULL)-start; Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - END (PID: %u, QN: %u/%u, ET: %u) ***\n", config.name, config.type, writer_pid, idata->qn, saved_index, idata->elap_time); if (config.sql_trigger_exec) { if (!config.debug) idata->elap_time = time(NULL)-start; SQL_SetENV_child(idata); } }
/** * 32-bit write to a HPET timer register. * * @returns Strict VBox status code. * * @param pThis The HPET state. * @param idxReg The register being written to. * @param u32NewValue The value being written. * * @remarks The caller should not hold the device lock, unless it also holds * the TM lock. */ static int hpetTimerRegWrite32(HPET *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t u32NewValue) { Assert(!PDMCritSectIsOwner(&pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer))); if ( iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities) || iTimerNo >= RT_ELEMENTS(pThis->aTimers) ) /* Parfait - see above. */ { static unsigned s_cOccurences = 0; if (s_cOccurences++ < 10) LogRel(("HPET: using timer above configured range: %d\n", iTimerNo)); return VINF_SUCCESS; } HPETTIMER *pHpetTimer = &pThis->aTimers[iTimerNo]; switch (iTimerReg) { case HPET_TN_CFG: { DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); uint64_t u64Mask = HPET_TN_CFG_WRITE_MASK; Log(("write HPET_TN_CFG: %d: %x\n", iTimerNo, u32NewValue)); if (pHpetTimer->u64Config & HPET_TN_PERIODIC_CAP) u64Mask |= HPET_TN_PERIODIC; if (pHpetTimer->u64Config & HPET_TN_SIZE_CAP) u64Mask |= HPET_TN_32BIT; else u32NewValue &= ~HPET_TN_32BIT; if (u32NewValue & HPET_TN_32BIT) { Log(("setting timer %d to 32-bit mode\n", iTimerNo)); pHpetTimer->u64Cmp = (uint32_t)pHpetTimer->u64Cmp; pHpetTimer->u64Period = (uint32_t)pHpetTimer->u64Period; } if ((u32NewValue & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL) { static unsigned s_cOccurences = 0; if (s_cOccurences++ < 10) LogRel(("level-triggered config not yet supported\n")); AssertFailed(); } /* We only care about lower 32-bits so far */ pHpetTimer->u64Config = hpetUpdateMasked(u32NewValue, pHpetTimer->u64Config, u64Mask); DEVHPET_UNLOCK(pThis); break; } case HPET_TN_CFG + 4: /* Interrupt capabilities - read only. */ { Log(("write HPET_TN_CFG + 4, useless\n")); break; } case HPET_TN_CMP: /* lower bits of comparator register */ { DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); Log(("write HPET_TN_CMP on %d: %#x\n", iTimerNo, u32NewValue)); if (pHpetTimer->u64Config & HPET_TN_PERIODIC) pHpetTimer->u64Period = RT_MAKE_U64(u32NewValue, RT_HI_U32(pHpetTimer->u64Period)); pHpetTimer->u64Cmp = RT_MAKE_U64(u32NewValue, RT_HI_U32(pHpetTimer->u64Cmp)); pHpetTimer->u64Config &= ~HPET_TN_SETVAL; Log2(("after HPET_TN_CMP cmp=%#llx per=%#llx\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period)); if (pThis->u64HpetConfig & HPET_CFG_ENABLE) hpetProgramTimer(pHpetTimer); DEVHPET_UNLOCK_BOTH(pThis); break; } case HPET_TN_CMP + 4: /* upper bits of comparator register */ { DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); Log(("write HPET_TN_CMP + 4 on %d: %#x\n", iTimerNo, u32NewValue)); if (!hpet32bitTimer(pHpetTimer)) { if (pHpetTimer->u64Config & HPET_TN_PERIODIC) pHpetTimer->u64Period = RT_MAKE_U64(RT_LO_U32(pHpetTimer->u64Period), u32NewValue); pHpetTimer->u64Cmp = RT_MAKE_U64(RT_LO_U32(pHpetTimer->u64Cmp), u32NewValue); Log2(("after HPET_TN_CMP+4 cmp=%llx per=%llx tmr=%d\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period, iTimerNo)); pHpetTimer->u64Config &= ~HPET_TN_SETVAL; if (pThis->u64HpetConfig & HPET_CFG_ENABLE) hpetProgramTimer(pHpetTimer); } DEVHPET_UNLOCK_BOTH(pThis); break; } case HPET_TN_ROUTE: { Log(("write HPET_TN_ROUTE\n")); break; } case HPET_TN_ROUTE + 4: { Log(("write HPET_TN_ROUTE + 4\n")); break; } default: { static unsigned s_cOccurences = 0; if (s_cOccurences++ < 10) LogRel(("invalid timer register write: %d\n", iTimerReg)); break; } } return VINF_SUCCESS; }
/** * Verifies randomly allocating and freeing variables. * * @param[in] aSizeLimit The maximum allocation size. * @param[in] aSeed The seed for generating random sizes. * */ void TestAllocateRandomly(size_t aSizeLimit, unsigned int aSeed) { struct Node { Node * mNext; size_t mSize; }; ot::Utils::Heap heap; Node head; size_t nnodes = 0; srand(aSeed); const size_t totalSize = heap.GetFreeSize(); Node * last = &head; do { size_t size = sizeof(Node) + static_cast<size_t>(rand()) % aSizeLimit; Log("TestAllocateRandomly allocating %zu bytes...", size); last->mNext = static_cast<Node *>(heap.CAlloc(1, size)); // No more memory for allocation. if (last->mNext == NULL) { break; } VerifyOrQuit(last->mNext->mNext == NULL, "TestAllocateRandomly memory not initialized to zero!\n"); last = last->mNext; last->mSize = size; ++nnodes; // 50% probability to randomly free a node. size_t freeIndex = static_cast<size_t>(rand()) % (nnodes * 2); if (freeIndex > nnodes) { freeIndex /= 2; Node *prev = &head; while (freeIndex--) { prev = prev->mNext; } Node *curr = prev->mNext; Log("TestAllocateRandomly freeing %zu bytes...", curr->mSize); prev->mNext = curr->mNext; heap.Free(curr); if (last == curr) { last = prev; } --nnodes; } } while (true); last = head.mNext; while (last) { Node *next = last->mNext; Log("TestAllocateRandomly freeing %zu bytes...", last->mSize); heap.Free(last); last = next; } VerifyOrQuit(heap.IsClean() && heap.GetFreeSize() == totalSize, "TestAllocateRandomly heap not clean after freeing all!\n"); }
/** * Read a 32-bit HPET register. * * @returns Strict VBox status code. * @param pThis The HPET state. * @param idxReg The register to read. * @param pu32Value Where to return the register value. * * @remarks The caller must not own the device lock if HPET_COUNTER is read. */ static int hpetConfigRegRead32(HPET *pThis, uint32_t idxReg, uint32_t *pu32Value) { Assert(!PDMCritSectIsOwner(&pThis->CritSect) || (idxReg != HPET_COUNTER && idxReg != HPET_COUNTER + 4)); uint32_t u32Value; switch (idxReg) { case HPET_ID: DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ); u32Value = pThis->u32Capabilities; DEVHPET_UNLOCK(pThis); Log(("read HPET_ID: %#x\n", u32Value)); break; case HPET_PERIOD: DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ); u32Value = pThis->u32Period; DEVHPET_UNLOCK(pThis); Log(("read HPET_PERIOD: %#x\n", u32Value)); break; case HPET_CFG: DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ); u32Value = (uint32_t)pThis->u64HpetConfig; DEVHPET_UNLOCK(pThis); Log(("read HPET_CFG: %#x\n", u32Value)); break; case HPET_CFG + 4: DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ); u32Value = (uint32_t)(pThis->u64HpetConfig >> 32); DEVHPET_UNLOCK(pThis); Log(("read of HPET_CFG + 4: %#x\n", u32Value)); break; case HPET_COUNTER: case HPET_COUNTER + 4: { DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_READ); uint64_t u64Ticks; if (pThis->u64HpetConfig & HPET_CFG_ENABLE) u64Ticks = hpetGetTicks(pThis); else u64Ticks = pThis->u64HpetCounter; DEVHPET_UNLOCK_BOTH(pThis); /** @todo is it correct? */ u32Value = (idxReg == HPET_COUNTER) ? (uint32_t)u64Ticks : (uint32_t)(u64Ticks >> 32); Log(("read HPET_COUNTER: %s part value %x (%#llx)\n", (idxReg == HPET_COUNTER) ? "low" : "high", u32Value, u64Ticks)); break; } case HPET_STATUS: DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ); u32Value = (uint32_t)pThis->u64Isr; DEVHPET_UNLOCK(pThis); Log(("read HPET_STATUS: %#x\n", u32Value)); break; default: Log(("invalid HPET register read: %x\n", idxReg)); u32Value = 0; break; } *pu32Value = u32Value; return VINF_SUCCESS; }
PhotonMapIntegrator(const Properties &props) : SamplingIntegrator(props), m_parentIntegrator(NULL) { /* Number of lsamples for direct illumination */ m_directSamples = props.getInteger("directSamples", 16); /* Number of BSDF samples when intersecting a glossy material */ m_glossySamples = props.getInteger("glossySamples", 32); /* Depth to start using russian roulette when tracing photons */ m_rrDepth = props.getInteger("rrDepth", 5); /* Longest visualized path length (\c -1 = infinite). A value of \c 1 will visualize only directly visible light sources. \c 2 will lead to single-bounce (direct-only) illumination, and so on. */ m_maxDepth = props.getInteger("maxDepth", -1); /** * When encountering an ideally specular material, the photon mapper places * a sample on each lobe (e.g. reflection *and* transmission). This leads * to an exponential growth in running time but greatly reduces variance and * is therefore usually worth it. This parameter specifies after how many * bounces this behavior should be stopped. */ m_maxSpecularDepth = props.getInteger("maxSpecularDepth", 4); /* Granularity of photon tracing work units (in shot particles, 0 => decide automatically) */ m_granularity = props.getInteger("granularity", 0); /* Number of photons to collect for the global photon map */ m_globalPhotons = props.getSize("globalPhotons", 250000); /* Number of photons to collect for the caustic photon map */ m_causticPhotons = props.getSize("causticPhotons", 250000); /* Number of photons to collect for the volumetric photon map */ m_volumePhotons = props.getSize("volumePhotons", 250000); /* Max. radius of lookups in the global photon map (relative to the scene size) */ m_globalLookupRadiusRel = props.getFloat("globalLookupRadius", 0.05f); /* Max. radius of lookups in the caustic photon map (relative to the scene size) */ m_causticLookupRadiusRel = props.getFloat("causticLookupRadius", 0.0125f); /* Minimum amount of photons to consider a photon map lookup valid */ int lookupSize = props.getInteger("lookupSize", 120); /* Minimum amount of photons to consider a volumetric photon map lookup valid */ m_globalLookupSize = props.getInteger("globalLookupSize", lookupSize); /* Maximum number of results for caustic photon map lookups */ m_causticLookupSize = props.getInteger("causticLookupSize", lookupSize); /* Approximate number of volume photons to be used in a lookup */ m_volumeLookupSize = props.getInteger("volumeLookupSize", lookupSize); /* Should photon gathering steps exclusively run on the local machine? */ m_gatherLocally = props.getBoolean("gatherLocally", true); /* Indicates if the gathering steps should be canceled if not enough photons are generated. */ m_autoCancelGathering = props.getBoolean("autoCancelGathering", true); /* When this flag is set to true, contributions from directly * visible emitters will not be included in the rendered image */ m_hideEmitters = props.getBoolean("hideEmitters", false); if (m_maxDepth == 0) { Log(EError, "maxDepth must be greater than zero!"); } else if (m_maxDepth == -1) { /** * An infinite depth is currently not supported, since * the photon tracing step uses a Halton sequence * that is based on a finite-sized prime number table */ m_maxDepth = 128; } m_causticPhotonMapID = m_globalPhotonMapID = m_breID = 0; }
/** * 32-bit write to a config register. * * @returns Strict VBox status code. * * @param pThis The HPET state. * @param idxReg The register being written to. * @param u32NewValue The value being written. * * @remarks The caller should not hold the device lock, unless it also holds * the TM lock. */ static int hpetConfigRegWrite32(HPET *pThis, uint32_t idxReg, uint32_t u32NewValue) { Assert(!PDMCritSectIsOwner(&pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer))); int rc = VINF_SUCCESS; switch (idxReg) { case HPET_ID: case HPET_ID + 4: { Log(("write HPET_ID, useless\n")); break; } case HPET_CFG: { DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); uint32_t const iOldValue = (uint32_t)(pThis->u64HpetConfig); Log(("write HPET_CFG: %x (old %x)\n", u32NewValue, iOldValue)); /* * This check must be here, before actual update, as hpetLegacyMode * may request retry in R3 - so we must keep state intact. */ if ( ((iOldValue ^ u32NewValue) & HPET_CFG_LEGACY) && pThis->pHpetHlpR3 != NIL_RTR3PTR) { #ifdef IN_RING3 rc = pThis->pHpetHlpR3->pfnSetLegacyMode(pThis->pDevInsR3, RT_BOOL(u32NewValue & HPET_CFG_LEGACY)); if (rc != VINF_SUCCESS) #else rc = VINF_IOM_R3_MMIO_WRITE; #endif { DEVHPET_UNLOCK_BOTH(pThis); break; } } pThis->u64HpetConfig = hpetUpdateMasked(u32NewValue, iOldValue, HPET_CFG_WRITE_MASK); uint32_t const cTimers = HPET_CAP_GET_TIMERS(pThis->u32Capabilities); if (hpetBitJustSet(iOldValue, u32NewValue, HPET_CFG_ENABLE)) { /** @todo Only get the time stamp once when reprogramming? */ /* Enable main counter and interrupt generation. */ pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter) - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer)); for (uint32_t i = 0; i < cTimers; i++) if (pThis->aTimers[i].u64Cmp != hpetInvalidValue(&pThis->aTimers[i])) hpetProgramTimer(&pThis->aTimers[i]); } else if (hpetBitJustCleared(iOldValue, u32NewValue, HPET_CFG_ENABLE)) { /* Halt main counter and disable interrupt generation. */ pThis->u64HpetCounter = hpetGetTicks(pThis); for (uint32_t i = 0; i < cTimers; i++) TMTimerStop(pThis->aTimers[i].CTX_SUFF(pTimer)); } DEVHPET_UNLOCK_BOTH(pThis); break; } case HPET_CFG + 4: { DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); pThis->u64HpetConfig = hpetUpdateMasked((uint64_t)u32NewValue << 32, pThis->u64HpetConfig, UINT64_C(0xffffffff00000000)); Log(("write HPET_CFG + 4: %x -> %#llx\n", u32NewValue, pThis->u64HpetConfig)); DEVHPET_UNLOCK(pThis); break; } case HPET_STATUS: { DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); /* Clear ISR for all set bits in u32NewValue, see p. 14 of the HPET spec. */ pThis->u64Isr &= ~((uint64_t)u32NewValue); Log(("write HPET_STATUS: %x -> ISR=%#llx\n", u32NewValue, pThis->u64Isr)); DEVHPET_UNLOCK(pThis); break; } case HPET_STATUS + 4: { Log(("write HPET_STATUS + 4: %x\n", u32NewValue)); if (u32NewValue != 0) { static unsigned s_cOccurrences = 0; if (s_cOccurrences++ < 10) LogRel(("Writing HPET_STATUS + 4 with non-zero, ignored\n")); } break; } case HPET_COUNTER: { DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); pThis->u64HpetCounter = RT_MAKE_U64(u32NewValue, RT_HI_U32(pThis->u64HpetCounter)); Log(("write HPET_COUNTER: %#x -> %llx\n", u32NewValue, pThis->u64HpetCounter)); DEVHPET_UNLOCK(pThis); break; } case HPET_COUNTER + 4: { DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); pThis->u64HpetCounter = RT_MAKE_U64(RT_LO_U32(pThis->u64HpetCounter), u32NewValue); Log(("write HPET_COUNTER + 4: %#x -> %llx\n", u32NewValue, pThis->u64HpetCounter)); DEVHPET_UNLOCK(pThis); break; } default: { static unsigned s_cOccurences = 0; if (s_cOccurences++ < 10) LogRel(("invalid HPET config write: %x\n", idxReg)); break; } } return rc; }
void OBS::EncodeLoop() { QWORD streamTimeStart = GetQPCTimeNS(); QWORD frameTimeNS = 1000000000/fps; bool bufferedFrames = true; //to avoid constantly polling number of frames int numTotalDuplicatedFrames = 0, numTotalFrames = 0; bufferedTimes.Clear(); bool bUsingQSV = videoEncoder->isQSV();//GlobalConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0; QWORD sleepTargetTime = streamTimeStart+frameTimeNS; latestVideoTime = firstSceneTimestamp = streamTimeStart/1000000; latestVideoTimeNS = streamTimeStart; firstFrameTimestamp = 0; EncoderPicture *lastPic = NULL; CircularList<QWORD> bufferedTimes; while(!bShutdownEncodeThread || (bufferedFrames && !bTestStream)) { SleepToNS(sleepTargetTime += (frameTimeNS/2)); latestVideoTime = sleepTargetTime/1000000; latestVideoTimeNS = sleepTargetTime; SetEvent(hVideoEvent); SleepToNS(sleepTargetTime += (frameTimeNS/2)); bufferedTimes << latestVideoTime; if (curFramePic && firstFrameTimestamp) { while (bufferedTimes[0] < firstFrameTimestamp) bufferedTimes.Remove(0); DWORD curFrameTimestamp = DWORD(bufferedTimes[0] - firstFrameTimestamp); bufferedTimes.Remove(0); profileIn("encoder thread frame"); FrameProcessInfo frameInfo; frameInfo.firstFrameTime = firstFrameTimestamp; frameInfo.frameTimestamp = curFrameTimestamp; frameInfo.pic = curFramePic; if (lastPic == frameInfo.pic) numTotalDuplicatedFrames++; if(bUsingQSV) curFramePic->mfxOut->Data.TimeStamp = curFrameTimestamp; else curFramePic->picOut->i_pts = curFrameTimestamp; ProcessFrame(frameInfo); if (bShutdownEncodeThread) bufferedFrames = videoEncoder->HasBufferedFrames(); lastPic = frameInfo.pic; profileOut; numTotalFrames++; } } //flush all video frames in the "scene buffering time" buffer if (firstFrameTimestamp && bufferedVideo.Num()) { QWORD startTime = GetQPCTimeMS(); DWORD baseTimestamp = bufferedVideo[0].timestamp; for(UINT i=0; i<bufferedVideo.Num(); i++) { //we measure our own time rather than sleep between frames due to potential sleep drift QWORD curTime; do { curTime = GetQPCTimeMS(); OSSleep (1); } while (curTime - startTime < bufferedVideo[i].timestamp - baseTimestamp); SendFrame(bufferedVideo[i], firstFrameTimestamp); bufferedVideo[i].Clear(); numTotalFrames++; } bufferedVideo.Clear(); } Log(TEXT("Total frames encoded: %d, total frames duplicated %d (%0.2f%%)"), numTotalFrames, numTotalDuplicatedFrames, (double(numTotalDuplicatedFrames)/double(numTotalFrames))*100.0); SetEvent(hVideoEvent); bShutdownVideoThread = true; }
// IExecuteCommandApplicationHostEnvironment IFACEMETHODIMP GetValue(AHE_TYPE *aLaunchType) { Log(L"IExecuteCommandApplicationHostEnvironment::GetValue()"); *aLaunchType = GetLaunchType(); return S_OK; }
// routines are loosely based upon the script provided in // "Spectra and Pseudospectra: The Behavior of Nonnormal Matrices and Operators" namespace El { // P_{i,j} = 2^{-n} choose(n+1,2i-j+1) alpha_{j+1} / alpha_{i+1} template<typename F> void Riffle( Matrix<F>& P, Int n ) { DEBUG_ONLY(CSE cse("Riffle")) typedef Base<F> Real; auto logBinom = LogBinomial<Real>( n+1 ); auto logEuler = LogEulerian<Real>( n ); const Real gamma = n*Log(Real(2)); P.Resize( n, n ); auto riffleFill = [&]( Int i, Int j ) -> F { const Int k = 2*i - j + 1; if( k >= 0 && k <= n+1 ) return Exp(logBinom[k]-gamma+logEuler[j]-logEuler[i]); else return Base<F>(0); }; IndexDependentFill( P, function<F(Int,Int)>(riffleFill) ); } template<typename F> void Riffle( AbstractDistMatrix<F>& P, Int n )
MQTTPacket* MQTTClient_waitfor(MQTTClient handle, int packet_type, int* rc, long timeout) { MQTTPacket* pack = NULL; MQTTClients* m = handle; START_TIME_TYPE start = MQTTClient_start_clock(); FUNC_ENTRY; if (((MQTTClients*)handle) == NULL) { *rc = MQTTCLIENT_FAILURE; goto exit; } if (running) { if (packet_type == CONNECT) { if ((*rc = Thread_wait_sem(m->connect_sem)) == 0) *rc = m->rc; } else if (packet_type == CONNACK) *rc = Thread_wait_sem(m->connack_sem); else if (packet_type == SUBACK) *rc = Thread_wait_sem(m->suback_sem); else if (packet_type == UNSUBACK) *rc = Thread_wait_sem(m->unsuback_sem); if (*rc == 0 && packet_type != CONNECT && m->pack == NULL) Log(TRACE_MIN, -1, "waitfor unexpectedly is NULL for client %s, packet_type %d", m->c->clientID, packet_type); pack = m->pack; } else { *rc = TCPSOCKET_COMPLETE; while (1) { int sock = -1; pack = MQTTClient_cycle(&sock, 100L, rc); if (sock == m->c->net.socket) { if (pack && (pack->header.bits.type == packet_type)) break; if (m->c->connect_state == 1) { int error; socklen_t len = sizeof(error); if ((*rc = getsockopt(m->c->net.socket, SOL_SOCKET, SO_ERROR, (char*)&error, &len)) == 0) *rc = error; break; } #if defined(OPENSSL) else if (m->c->connect_state == 2) { *rc = SSLSocket_connect(m->c->net.ssl, sock); if (*rc == SSL_FATAL) break; else if (*rc == 1) /* rc == 1 means SSL connect has finished and succeeded */ { if (!m->c->cleansession && m->c->session == NULL) m->c->session = SSL_get1_session(m->c->net.ssl); break; } } #endif else if (m->c->connect_state == 3) { int error; socklen_t len = sizeof(error); if (getsockopt(m->c->net.socket, SOL_SOCKET, SO_ERROR, &error, &len) == 0) { if (error) { *rc = error; break; } } } } if (MQTTClient_elapsed(start) > timeout) { pack = NULL; break; } } } exit: FUNC_EXIT_RC(*rc); return pack; }