WD_HPATH wdCreatePath(WD_HCANVAS hCanvas) { if(d2d_enabled()) { dummy_ID2D1PathGeometry* g; HRESULT hr; wd_lock(); hr = dummy_ID2D1Factory_CreatePathGeometry(d2d_factory, &g); wd_unlock(); if(FAILED(hr)) { WD_TRACE_HR("wdCreatePath: " "ID2D1Factory::CreatePathGeometry() failed."); return NULL; } return (WD_HPATH) g; } else { dummy_GpPath* p; int status; status = gdix_vtable->fn_CreatePath(dummy_FillModeAlternate, &p); if(status != 0) { WD_TRACE("wdCreatePath: GdipCreatePath() failed. [%d]", status); return NULL; } return (WD_HPATH) p; } }
bool unregister_watchdog(watchdog_t *wd) { watchdog_t *p; bool ok = false; if (!wd_is_init) { Jmsg0(NULL, M_ABORT, 0, _("BUG! unregister_watchdog_unlocked called before start_watchdog\n")); } wd_lock(); foreach_dlist(p, wd_queue) { if (wd == p) { wd_queue->remove(wd); Dmsg1(800, "Unregistered watchdog %p\n", wd); ok = true; goto get_out; } } foreach_dlist(p, wd_inactive) { if (wd == p) { wd_inactive->remove(wd); Dmsg1(800, "Unregistered inactive watchdog %p\n", wd); ok = true; goto get_out; } } Dmsg1(800, "Failed to unregister watchdog %p\n", wd); get_out: wd_unlock(); ping_watchdog(); return ok; }
bool register_watchdog(watchdog_t *wd) { if (!wd_is_init) { Jmsg0(NULL, M_ABORT, 0, _("BUG! register_watchdog called before start_watchdog\n")); } if (wd->callback == NULL) { Jmsg1(NULL, M_ABORT, 0, _("BUG! Watchdog %p has NULL callback\n"), wd); } if (wd->interval == 0) { Jmsg1(NULL, M_ABORT, 0, _("BUG! Watchdog %p has zero interval\n"), wd); } wd_lock(); wd->next_fire = watchdog_time + wd->interval; wd_queue->append(wd); Dmsg3(800, "Registered watchdog %p, interval %d%s\n", wd, wd->interval, wd->one_shot ? " one shot" : ""); wd_unlock(); ping_watchdog(); return false; }
/* * This is the thread that walks the watchdog queue * and when a queue item fires, the callback is * invoked. If it is a one shot, the queue item * is moved to the inactive queue. */ extern "C" void *watchdog_thread(void *arg) { struct timespec timeout; struct timeval tv; struct timezone tz; utime_t next_time; set_jcr_in_tsd(INVALID_JCR); Dmsg0(800, "NicB-reworked watchdog thread entered\n"); while (!quit) { watchdog_t *p; /* * * NOTE. lock_jcr_chain removed, but the message below * was left until we are sure there are no deadlocks. * * We lock the jcr chain here because a good number of the * callback routines lock the jcr chain. We need to lock * it here *before* the watchdog lock because the SD message * thread first locks the jcr chain, then when closing the * job locks the watchdog chain. If the two threads do not * lock in the same order, we get a deadlock -- each holds * the other's needed lock. */ wd_lock(); walk_list: watchdog_time = time(NULL); next_time = watchdog_time + watchdog_sleep_time; foreach_dlist(p, wd_queue) { if (p->next_fire <= watchdog_time) { /* Run the callback */ Dmsg2(3400, "Watchdog callback p=0x%p fire=%d\n", p, p->next_fire); p->callback(p); /* Reschedule (or move to inactive list if it's a one-shot timer) */ if (p->one_shot) { wd_queue->remove(p); wd_inactive->append(p); goto walk_list; } else { p->next_fire = watchdog_time + p->interval; } } if (p->next_fire <= next_time) { next_time = p->next_fire; } } wd_unlock(); /* * Wait sleep time or until someone wakes us */ gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + next_time - time(NULL); while (timeout.tv_nsec >= 1000000000) { timeout.tv_nsec -= 1000000000; timeout.tv_sec++; } Dmsg1(1900, "pthread_cond_timedwait %d\n", timeout.tv_sec - tv.tv_sec); /* Note, this unlocks mutex during the sleep */ P(timer_mutex); pthread_cond_timedwait(&timer, &timer_mutex, &timeout); V(timer_mutex); } Dmsg0(800, "NicB-reworked watchdog thread exited\n"); return NULL; }
WD_HCANVAS wdCreateCanvasWithHDC(HDC hDC, const RECT* pRect, DWORD dwFlags) { if(d2d_enabled()) { dummy_D2D1_RENDER_TARGET_PROPERTIES props = { dummy_D2D1_RENDER_TARGET_TYPE_DEFAULT, { dummy_DXGI_FORMAT_B8G8R8A8_UNORM, dummy_D2D1_ALPHA_MODE_PREMULTIPLIED }, 0.0f, 0.0f, ((dwFlags & WD_CANVAS_NOGDICOMPAT) ? 0 : dummy_D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE), dummy_D2D1_FEATURE_LEVEL_DEFAULT }; d2d_canvas_t* c; dummy_ID2D1DCRenderTarget* target; HRESULT hr; wd_lock(); hr = dummy_ID2D1Factory_CreateDCRenderTarget(d2d_factory, &props, &target); wd_unlock(); if(FAILED(hr)) { WD_TRACE_HR("wdCreateCanvasWithHDC: " "ID2D1Factory::CreateDCRenderTarget() failed."); goto err_CreateDCRenderTarget; } hr = dummy_ID2D1DCRenderTarget_BindDC(target, hDC, pRect); if(FAILED(hr)) { WD_TRACE_HR("wdCreateCanvasWithHDC: " "ID2D1Factory::BindDC() failed."); goto err_BindDC; } c = d2d_canvas_alloc((dummy_ID2D1RenderTarget*)target, D2D_CANVASTYPE_DC, pRect->right - pRect->left, (dwFlags & WD_CANVAS_LAYOUTRTL)); if(c == NULL) { WD_TRACE("wdCreateCanvasWithHDC: d2d_canvas_alloc() failed."); goto err_d2d_canvas_alloc; } /* make sure text anti-aliasing is clear type */ dummy_ID2D1RenderTarget_SetTextAntialiasMode(c->target, dummy_D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE); return (WD_HCANVAS) c; err_d2d_canvas_alloc: err_BindDC: dummy_ID2D1RenderTarget_Release((dummy_ID2D1RenderTarget*)target); err_CreateDCRenderTarget: return NULL; } else { BOOL use_doublebuffer = (dwFlags & WD_CANVAS_DOUBLEBUFFER); gdix_canvas_t* c; c = gdix_canvas_alloc(hDC, (use_doublebuffer ? pRect : NULL), pRect->right - pRect->left, (dwFlags & WD_CANVAS_LAYOUTRTL)); if(c == NULL) { WD_TRACE("wdCreateCanvasWithHDC: gdix_canvas_alloc() failed."); return NULL; } return (WD_HCANVAS) c; } }
WD_HCANVAS wdCreateCanvasWithPaintStruct(HWND hWnd, PAINTSTRUCT* pPS, DWORD dwFlags) { RECT rect; GetClientRect(hWnd, &rect); if(d2d_enabled()) { dummy_D2D1_RENDER_TARGET_PROPERTIES props = { dummy_D2D1_RENDER_TARGET_TYPE_DEFAULT, { dummy_DXGI_FORMAT_B8G8R8A8_UNORM, dummy_D2D1_ALPHA_MODE_PREMULTIPLIED }, 0.0f, 0.0f, ((dwFlags & WD_CANVAS_NOGDICOMPAT) ? 0 : dummy_D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE), dummy_D2D1_FEATURE_LEVEL_DEFAULT }; dummy_D2D1_HWND_RENDER_TARGET_PROPERTIES props2; d2d_canvas_t* c; dummy_ID2D1HwndRenderTarget* target; HRESULT hr; props2.hwnd = hWnd; props2.pixelSize.width = rect.right - rect.left; props2.pixelSize.height = rect.bottom - rect.top; props2.presentOptions = dummy_D2D1_PRESENT_OPTIONS_NONE; wd_lock(); /* Note ID2D1HwndRenderTarget is implicitly double-buffered. */ hr = dummy_ID2D1Factory_CreateHwndRenderTarget(d2d_factory, &props, &props2, &target); wd_unlock(); if(FAILED(hr)) { WD_TRACE_HR("wdCreateCanvasWithPaintStruct: " "ID2D1Factory::CreateHwndRenderTarget() failed."); return NULL; } c = d2d_canvas_alloc((dummy_ID2D1RenderTarget*)target, D2D_CANVASTYPE_HWND, rect.right, (dwFlags & WD_CANVAS_LAYOUTRTL)); if(c == NULL) { WD_TRACE("wdCreateCanvasWithPaintStruct: d2d_canvas_alloc() failed."); dummy_ID2D1RenderTarget_Release((dummy_ID2D1RenderTarget*)target); return NULL; } /* make sure text anti-aliasing is clear type */ dummy_ID2D1RenderTarget_SetTextAntialiasMode(c->target, dummy_D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE); return (WD_HCANVAS) c; } else { BOOL use_doublebuffer = (dwFlags & WD_CANVAS_DOUBLEBUFFER); gdix_canvas_t* c; c = gdix_canvas_alloc(pPS->hdc, (use_doublebuffer ? &pPS->rcPaint : NULL), rect.right, (dwFlags & WD_CANVAS_LAYOUTRTL)); if(c == NULL) { WD_TRACE("wdCreateCanvasWithPaintStruct: gdix_canvas_alloc() failed."); return NULL; } return (WD_HCANVAS) c; } }