Browse Source

Autoscan for new devices on Windows when DBT_DEVNODES_CHANGED message is broadcast

Luke Dashjr 12 years ago
parent
commit
a6d471fcce
1 changed files with 65 additions and 0 deletions
  1. 65 0
      miner.c

+ 65 - 0
miner.c

@@ -51,6 +51,7 @@
 #else
 #include <winsock2.h>
 #include <windows.h>
+#include <dbt.h>
 #endif
 #include <ccan/opt/opt.h>
 #include <jansson.h>
@@ -172,6 +173,11 @@ int httpsrv_port = -1;
 int stratumsrv_port = -1;
 #endif
 
+#ifdef WIN32
+bool opt_hotplug = 1;
+#else
+const bool opt_hotplug;
+#endif
 struct string_elist *scan_devices;
 static struct string_elist *opt_set_device_list;
 bool opt_force_dev_init;
@@ -2094,6 +2100,15 @@ static struct opt_table opt_config_table[] = {
 	OPT_WITHOUT_ARG("--no-getwork",
 			opt_set_invbool, &want_getwork,
 			"Disable getwork support"),
+	OPT_WITHOUT_ARG("--no-hotplug",
+#ifdef WIN32
+	                opt_set_invbool, &opt_hotplug,
+	                "Disable hotplug detection"
+#else
+	                set_null, &opt_hotplug,
+	                opt_hidden
+#endif
+	),
 	OPT_WITHOUT_ARG("--no-longpoll",
 			opt_set_invbool, &want_longpoll,
 			"Disable X-Long-Polling support"),
@@ -11001,6 +11016,51 @@ int scan_serial(const char *s)
 	return create_new_cgpus(_scan_serial, (void*)s);
 }
 
+#ifdef WIN32
+LRESULT CALLBACK hotplug_win_callback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	if (msg == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED)
+	{
+		applog(LOG_DEBUG, "%s: Received DBT_DEVNODES_CHANGED event", __func__);
+		scan_serial(NULL);
+	}
+	return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static
+void *hotplug_thread(__maybe_unused void *p)
+{
+	pthread_detach(pthread_self());
+	
+	WNDCLASS DummyWinCls = {
+		.lpszClassName = "BFGDummyWinCls",
+		.lpfnWndProc = hotplug_win_callback,
+	};
+	ATOM a = RegisterClass(&DummyWinCls);
+	if (unlikely(!a))
+		applogfailinfor(NULL, LOG_ERR, "RegisterClass", "%d", (int)GetLastError());
+	HWND hwnd = CreateWindow((void*)(intptr_t)a, NULL, WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
+	if (unlikely(!hwnd))
+		applogfailinfor(NULL, LOG_ERR, "CreateWindow", "%d", (int)GetLastError());
+	MSG msg;
+	while (GetMessage(&msg, NULL, 0, 0))
+	{
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+	}
+	quit(0, "WM_QUIT received");
+	return NULL;
+}
+
+static
+void hotplug_start()
+{
+	pthread_t pth;
+	if (unlikely(pthread_create(&pth, NULL, hotplug_thread, NULL)))
+		applog(LOG_ERR, "Failed to start hotplug thread");
+}
+#endif
+
 static void probe_pools(void)
 {
 	int i;
@@ -11619,6 +11679,11 @@ begin_bench:
 		stratumsrv_start();
 #endif
 
+#ifdef WIN32
+	if (opt_hotplug && !opt_scrypt)
+		hotplug_start();
+#endif
+
 #ifdef HAVE_CURSES
 	/* Create curses input thread for keyboard input. Create this last so
 	 * that we know all threads are created since this can call kill_work