driver-proxy.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright 2013 Luke Dashjr
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include <unistd.h>
  11. #include <pthread.h>
  12. #include <uthash.h>
  13. #include "deviceapi.h"
  14. #include "driver-proxy.h"
  15. #include "miner.h"
  16. #include "util.h"
  17. BFG_REGISTER_DRIVER(proxy_drv)
  18. static
  19. struct proxy_client *proxy_clients;
  20. static
  21. pthread_mutex_t proxy_clients_mutex = PTHREAD_MUTEX_INITIALIZER;
  22. static
  23. void prune_worklog()
  24. {
  25. struct proxy_client *client, *tmp;
  26. struct work *work, *tmp2;
  27. struct timeval tv_now;
  28. timer_set_now(&tv_now);
  29. mutex_lock(&proxy_clients_mutex);
  30. HASH_ITER(hh, proxy_clients, client, tmp)
  31. {
  32. HASH_ITER(hh, client->work, work, tmp2)
  33. {
  34. if (timer_elapsed(&work->tv_work_start, &tv_now) <= opt_expiry)
  35. break;
  36. HASH_DEL(client->work, work);
  37. free_work(work);
  38. }
  39. }
  40. mutex_unlock(&proxy_clients_mutex);
  41. }
  42. static
  43. pthread_t prune_worklog_pth;
  44. static
  45. void *prune_worklog_thread(void *userdata)
  46. {
  47. struct cgpu_info *cgpu = userdata;
  48. pthread_detach(pthread_self());
  49. RenameThread("PXY_pruner");
  50. while (!cgpu->shutdown)
  51. {
  52. prune_worklog();
  53. sleep(60);
  54. }
  55. return NULL;
  56. }
  57. static
  58. void proxy_first_client(struct cgpu_info *cgpu)
  59. {
  60. pthread_create(&prune_worklog_pth, NULL, prune_worklog_thread, cgpu);
  61. }
  62. struct proxy_client *proxy_find_or_create_client(const char *username)
  63. {
  64. struct proxy_client *client;
  65. struct cgpu_info *cgpu;
  66. char *user;
  67. int b;
  68. if (!username)
  69. return NULL;
  70. mutex_lock(&proxy_clients_mutex);
  71. HASH_FIND_STR(proxy_clients, username, client);
  72. if (!client)
  73. {
  74. user = strdup(username);
  75. cgpu = malloc(sizeof(*cgpu));
  76. client = malloc(sizeof(*client));
  77. *cgpu = (struct cgpu_info){
  78. .drv = &proxy_drv,
  79. .threads = 0,
  80. .device_data = client,
  81. .device_path = user,
  82. };
  83. timer_set_now(&cgpu->cgminer_stats.start_tv);
  84. if (unlikely(!create_new_cgpus(add_cgpu_live, cgpu)))
  85. {
  86. free(client);
  87. free(cgpu);
  88. free(user);
  89. return NULL;
  90. }
  91. *client = (struct proxy_client){
  92. .username = user,
  93. .cgpu = cgpu,
  94. };
  95. b = HASH_COUNT(proxy_clients);
  96. HASH_ADD_KEYPTR(hh, proxy_clients, client->username, strlen(user), client);
  97. mutex_unlock(&proxy_clients_mutex);
  98. if (!b)
  99. proxy_first_client(cgpu);
  100. }
  101. else
  102. mutex_unlock(&proxy_clients_mutex);
  103. return client;
  104. }
  105. #ifdef HAVE_CURSES
  106. static
  107. void proxy_wlogprint_status(struct cgpu_info *cgpu)
  108. {
  109. struct proxy_client *client = cgpu->device_data;
  110. wlogprint("Username: %s\n", client->username);
  111. }
  112. #endif
  113. struct device_drv proxy_drv = {
  114. .dname = "proxy",
  115. .name = "PXY",
  116. #ifdef HAVE_CURSES
  117. .proc_wlogprint_status = proxy_wlogprint_status,
  118. #endif
  119. };