worker.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /* Gearman server and library
  2. * Copyright (C) 2008 Brian Aker, Eric Day
  3. * All rights reserved.
  4. *
  5. * Use and distribution licensed under the BSD license. See
  6. * the COPYING file in the parent directory for full text.
  7. */
  8. /**
  9. * @file
  10. * @brief Server worker definitions
  11. */
  12. #include <libgearman-server/common.h>
  13. static gearman_server_worker_st *
  14. gearman_server_worker_create(gearman_server_con_st *con,
  15. gearman_server_function_st *function);
  16. /*
  17. * Public definitions
  18. */
  19. gearman_server_worker_st *
  20. gearman_server_worker_add(gearman_server_con_st *con, const char *function_name,
  21. size_t function_name_size, uint32_t timeout)
  22. {
  23. gearman_server_worker_st *worker;
  24. gearman_server_function_st *function= gearman_server_function_get(Server, function_name,
  25. function_name_size);
  26. if (function == NULL)
  27. {
  28. return NULL;
  29. }
  30. worker= gearman_server_worker_create(con, function);
  31. if (worker == NULL)
  32. {
  33. return NULL;
  34. }
  35. worker->timeout= timeout;
  36. return worker;
  37. }
  38. static gearman_server_worker_st *
  39. gearman_server_worker_create(gearman_server_con_st *con, gearman_server_function_st *function)
  40. {
  41. gearman_server_worker_st *worker;
  42. if (Server->free_worker_count > 0)
  43. {
  44. worker= Server->free_worker_list;
  45. GEARMAN_LIST_DEL(Server->free_worker, worker, con_)
  46. }
  47. else
  48. {
  49. worker= static_cast<gearman_server_worker_st *>(malloc(sizeof(gearman_server_worker_st)));
  50. if (not worker)
  51. {
  52. gearmand_merror("malloc", 0, sizeof(gearman_server_worker_st));
  53. return NULL;
  54. }
  55. }
  56. worker->job_count= 0;
  57. worker->timeout= 0;
  58. worker->con= con;
  59. GEARMAN_LIST_ADD(con->worker, worker, con_)
  60. worker->function= function;
  61. /* Add worker to the function list, which is a double-linked circular list. */
  62. if (function->worker_list == NULL)
  63. {
  64. function->worker_list= worker;
  65. worker->function_next= worker;
  66. worker->function_prev= worker;
  67. }
  68. else
  69. {
  70. worker->function_next= function->worker_list;
  71. worker->function_prev= function->worker_list->function_prev;
  72. worker->function_next->function_prev= worker;
  73. worker->function_prev->function_next= worker;
  74. }
  75. function->worker_count++;
  76. worker->job_list= NULL;
  77. return worker;
  78. }
  79. void gearman_server_worker_free(gearman_server_worker_st *worker)
  80. {
  81. /* If the worker was in the middle of a job, requeue it. */
  82. while (worker->job_list != NULL)
  83. {
  84. gearmand_error_t ret= gearman_server_job_queue(worker->job_list);
  85. if (ret != GEARMAN_SUCCESS)
  86. {
  87. gearmand_gerror_warn("gearman_server_job_queue", ret);
  88. }
  89. }
  90. GEARMAN_LIST_DEL(worker->con->worker, worker, con_)
  91. if (worker == worker->function_next)
  92. {
  93. worker->function->worker_list= NULL;
  94. }
  95. else
  96. {
  97. worker->function_next->function_prev= worker->function_prev;
  98. worker->function_prev->function_next= worker->function_next;
  99. if (worker == worker->function->worker_list)
  100. {
  101. worker->function->worker_list= worker->function_next;
  102. }
  103. }
  104. worker->function->worker_count--;
  105. if (Server->free_worker_count < GEARMAN_MAX_FREE_SERVER_WORKER)
  106. {
  107. GEARMAN_LIST_ADD(Server->free_worker, worker, con_)
  108. }
  109. else
  110. {
  111. gearmand_debug("free");
  112. free(worker);
  113. }
  114. }