1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Gearmand client and server library.
4 *
5 * Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2008 Brian Aker, Eric Day
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following disclaimer
18 * in the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * * The names of its contributors may not be used to endorse or
22 * promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
38
39 /**
40 * @file
41 * @brief Server function definitions
42 */
43
44 #include "gear_config.h"
45 #include "libgearman-server/common.h"
46
47 #include <cstring>
48 #include <memory>
49
50 /*
51 * Public definitions
52 */
53
_server_function_hash(const char * name,size_t size)54 static uint32_t _server_function_hash(const char *name, size_t size)
55 {
56 const char *ptr= name;
57 int32_t value= 0;
58
59 while (size--)
60 {
61 value += (int32_t)*ptr++;
62 value += (value << 10);
63 value ^= (value >> 6);
64 }
65
66 value += (value << 3);
67 value ^= (value >> 11);
68 value += (value << 15);
69
70 return (uint32_t)(value == 0 ? 1 : value);
71 }
72
73 #ifndef __INTEL_COMPILER
74 #pragma GCC diagnostic ignored "-Wold-style-cast"
75 #endif
76
gearman_server_function_create(gearman_server_st * server,const char * function_name,size_t function_name_size,uint32_t function_key)77 static gearman_server_function_st* gearman_server_function_create(gearman_server_st *server,
78 const char *function_name,
79 size_t function_name_size,
80 uint32_t function_key)
81 {
82 gearman_server_function_st* function= new (std::nothrow) gearman_server_function_st;
83
84 if (function == NULL)
85 {
86 gearmand_merror("new gearman_server_function_st", gearman_server_function_st, 0);
87 return NULL;
88 }
89
90 function->worker_count= 0;
91 function->job_count= 0;
92 function->job_total= 0;
93 function->job_running= 0;
94 memset(function->max_queue_size, GEARMAN_DEFAULT_MAX_QUEUE_SIZE, sizeof(uint32_t) * GEARMAN_JOB_PRIORITY_MAX);
95
96 function->function_name= new char[function_name_size +1];
97 if (function->function_name == NULL)
98 {
99 gearmand_merror("new[]", char, function_name_size +1);
100 delete function;
101 return NULL;
102 }
103
104 memcpy(function->function_name, function_name, function_name_size);
105 function->function_name[function_name_size]= 0;
106 function->function_name_size= function_name_size;
107 function->worker_list= NULL;
108 memset(function->job_list, 0,
109 sizeof(gearman_server_job_st *) * GEARMAN_JOB_PRIORITY_MAX);
110 memset(function->job_end, 0,
111 sizeof(gearman_server_job_st *) * GEARMAN_JOB_PRIORITY_MAX);
112 GEARMAN_HASH__ADD(server->function, function_key, function);
113 return function;
114 }
115
116 gearman_server_function_st *
gearman_server_function_get(gearman_server_st * server,const char * function_name,size_t function_name_size)117 gearman_server_function_get(gearman_server_st *server,
118 const char *function_name,
119 size_t function_name_size)
120 {
121 gearman_server_function_st *function;
122
123 uint32_t function_hash = _server_function_hash(function_name, function_name_size) % GEARMAND_DEFAULT_HASH_SIZE;
124 for (function= server->function_hash[function_hash]; function != NULL;
125 function= function->next)
126 {
127 if (function->function_name_size == function_name_size and
128 memcmp(function->function_name, function_name, function_name_size) == 0)
129 {
130 return function;
131 }
132 }
133
134 return gearman_server_function_create(server, function_name, function_name_size, function_hash);
135 }
136
gearman_server_function_free(gearman_server_st * server,gearman_server_function_st * function)137 void gearman_server_function_free(gearman_server_st *server, gearman_server_function_st *function)
138 {
139 uint32_t function_key;
140 function_key= _server_function_hash(function->function_name, function->function_name_size);
141 function_key= function_key % GEARMAND_DEFAULT_HASH_SIZE;
142 GEARMAN_HASH__DEL(server->function, function_key, function);
143 delete [] function->function_name;
144 delete function;
145 }
146