1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Gearmand client and server library.
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38 #include "gear_config.h"
39 #include <libgearman/common.h>
40 #include <libgearman/add.hpp>
41 #include <libgearman/universal.hpp>
42 #include <libgearman/do.hpp>
43
44 #include "libgearman/assert.hpp"
45
46 #include <cerrno>
47 #include <cstring>
48
client_do(gearman_client_st * client,gearman_command_t command,const char * function_name,const char * unique,const void * workload_str,size_t workload_size,size_t * result_size,gearman_return_t * ret_ptr)49 void *client_do(gearman_client_st *client, gearman_command_t command,
50 const char *function_name,
51 const char *unique,
52 const void *workload_str, size_t workload_size,
53 size_t *result_size, gearman_return_t *ret_ptr)
54 {
55 gearman_task_st do_task;
56 gearman_string_t function= { gearman_string_param_cstr(function_name) };
57 gearman_unique_t local_unique= gearman_unique_make(unique, unique ? strlen(unique) : 0);
58 gearman_string_t workload= { static_cast<const char*>(workload_str), workload_size };
59
60 // Set to zero in case of error
61 size_t unused_result_size;
62 if (result_size == NULL)
63 {
64 result_size= &unused_result_size;
65 }
66 *result_size= 0;
67
68 gearman_return_t unused;
69 if (ret_ptr == NULL)
70 {
71 ret_ptr= &unused;
72 }
73
74 if (client == NULL)
75 {
76 *ret_ptr= GEARMAN_INVALID_ARGUMENT;
77 return NULL;
78 }
79
80 gearman_task_st *do_task_ptr= add_task(*client, &do_task, NULL, command,
81 function,
82 local_unique,
83 workload,
84 time_t(0),
85 gearman_actions_do_default());
86 if (do_task_ptr == NULL)
87 {
88 *ret_ptr= gearman_universal_error_code(client->universal);
89 return NULL;
90 }
91
92 gearman_return_t ret= gearman_client_run_block_tasks(client, do_task_ptr);
93
94 const void *returnable= NULL;
95
96 // gearman_client_run_block_tasks failed
97 if (gearman_failed(ret))
98 {
99 gearman_error(client->universal, ret, "occured during gearman_client_run_tasks()");
100
101 *ret_ptr= ret;
102 *result_size= 0;
103 }
104 else // Now we check the task itself
105 {
106 assert(ret == GEARMAN_SUCCESS); // Programmer mistake
107 if (gearman_success(do_task_ptr->result_rc))
108 {
109 *ret_ptr= do_task_ptr->result_rc;
110 if (gearman_task_result(do_task_ptr))
111 {
112 gearman_string_t result= gearman_result_take_string(do_task_ptr->result_ptr);
113 *result_size= gearman_size(result);
114 returnable= gearman_c_str(result);
115 }
116 else // NULL SUCCESSFUL job
117 { }
118 }
119 else // gearman_client_run_block_tasks() was successful, but the task was not
120 {
121 gearman_error(client->universal, do_task_ptr->result_rc, "occured during gearman_client_run_tasks()");
122
123 *ret_ptr= do_task_ptr->result_rc;
124 *result_size= 0;
125 }
126 }
127
128 assert(client->task_list);
129 gearman_task_free(&do_task);
130 client->new_tasks= 0;
131 client->running_tasks= 0;
132
133 return const_cast<void *>(returnable);
134 }
135
client_do_background(gearman_client_st * client,gearman_command_t command,gearman_string_t & function,gearman_unique_t & unique,gearman_string_t & workload,gearman_job_handle_t job_handle)136 gearman_return_t client_do_background(gearman_client_st *client,
137 gearman_command_t command,
138 gearman_string_t &function,
139 gearman_unique_t &unique,
140 gearman_string_t &workload,
141 gearman_job_handle_t job_handle)
142 {
143 if (client == NULL)
144 {
145 return GEARMAN_INVALID_ARGUMENT;
146 }
147
148 gearman_task_st do_task;
149 gearman_task_st *do_task_ptr= add_task(*client, &do_task,
150 client,
151 command,
152 function,
153 unique,
154 workload,
155 time_t(0),
156 gearman_actions_do_default());
157 if (do_task_ptr == NULL)
158 {
159 return gearman_universal_error_code(client->universal);
160 }
161
162 gearman_task_clear_fn(do_task_ptr);
163
164 gearman_return_t ret= gearman_client_run_block_tasks(client, do_task_ptr);
165 assert(ret != GEARMAN_IO_WAIT);
166 if (ret != GEARMAN_IO_WAIT)
167 {
168 if (job_handle)
169 {
170 strncpy(job_handle, do_task.job_handle, GEARMAN_JOB_HANDLE_SIZE);
171 }
172 client->new_tasks= 0;
173 client->running_tasks= 0;
174 }
175 gearman_task_free(&do_task);
176
177 return ret;
178 }
179