Gearman Developer Documentation

libgearman-server/worker.c
Go to the documentation of this file.
00001 /* Gearman server and library
00002  * Copyright (C) 2008 Brian Aker, Eric Day
00003  * All rights reserved.
00004  *
00005  * Use and distribution licensed under the BSD license.  See
00006  * the COPYING file in the parent directory for full text.
00007  */
00008 
00014 #include "common.h"
00015 
00016 /*
00017  * Public definitions
00018  */
00019 
00020 gearman_server_worker_st *
00021 gearman_server_worker_add(gearman_server_con_st *con, const char *function_name,
00022                           size_t function_name_size, uint32_t timeout)
00023 {
00024   gearman_server_worker_st *worker;
00025   gearman_server_function_st *function;
00026 
00027   function= gearman_server_function_get(con->thread->server, function_name,
00028                                         function_name_size);
00029   if (function == NULL)
00030     return NULL;
00031 
00032   worker= gearman_server_worker_create(con, function, NULL);
00033   if (worker == NULL)
00034     return NULL;
00035 
00036   worker->timeout= timeout;
00037 
00038   return worker;
00039 }
00040 
00041 gearman_server_worker_st *
00042 gearman_server_worker_create(gearman_server_con_st *con,
00043                              gearman_server_function_st *function,
00044                              gearman_server_worker_st *worker)
00045 {
00046   gearman_server_st *server= con->thread->server;
00047 
00048   if (worker == NULL)
00049   {
00050     if (server->free_worker_count > 0)
00051     {
00052       worker= server->free_worker_list;
00053       GEARMAN_LIST_DEL(server->free_worker, worker, con_)
00054     }
00055     else
00056     {
00057       worker= (gearman_server_worker_st *)malloc(sizeof(gearman_server_worker_st));
00058       if (worker == NULL)
00059       {
00060         gearman_log_error(con->thread->gearman, "gearman_server_worker_create", "malloc");
00061         return NULL;
00062       }
00063     }
00064 
00065     worker->options.allocated= true;
00066   }
00067   else
00068     worker->options.allocated= false;
00069 
00070   worker->job_count= 0;
00071   worker->timeout= 0;
00072   worker->con= con;
00073   GEARMAN_LIST_ADD(con->worker, worker, con_)
00074   worker->function= function;
00075 
00076   /* Add worker to the function list, which is a double-linked circular list. */
00077   if (function->worker_list == NULL)
00078   {
00079     function->worker_list= worker;
00080     worker->function_next= worker;
00081     worker->function_prev= worker;
00082   }
00083   else
00084   {
00085     worker->function_next= function->worker_list;
00086     worker->function_prev= function->worker_list->function_prev;
00087     worker->function_next->function_prev= worker;
00088     worker->function_prev->function_next= worker;
00089   }
00090   function->worker_count++;
00091 
00092   worker->job_list= NULL;
00093 
00094   return worker;
00095 }
00096 
00097 void gearman_server_worker_free(gearman_server_worker_st *worker)
00098 {
00099   gearman_server_st *server= worker->con->thread->server;
00100 
00101   /* If the worker was in the middle of a job, requeue it. */
00102   while (worker->job_list != NULL)
00103     (void)gearman_server_job_queue(worker->job_list);
00104 
00105   GEARMAN_LIST_DEL(worker->con->worker, worker, con_)
00106 
00107   if (worker == worker->function_next)
00108     worker->function->worker_list= NULL;
00109   else
00110   {
00111     worker->function_next->function_prev= worker->function_prev;
00112     worker->function_prev->function_next= worker->function_next;
00113     if (worker == worker->function->worker_list)
00114       worker->function->worker_list= worker->function_next;
00115   }
00116   worker->function->worker_count--;
00117 
00118   if (worker->options.allocated)
00119   {
00120     if (server->free_worker_count < GEARMAN_MAX_FREE_SERVER_WORKER)
00121       GEARMAN_LIST_ADD(server->free_worker, worker, con_)
00122     else
00123       free(worker);
00124   }
00125 }