~ubuntu-branches/debian/sid/gearmand/sid

« back to all changes in this revision

Viewing changes to .pc/debian_patches_fix_spelling.patch/libgearman/client.cc

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2012-05-01 20:43:47 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20120501204347-qaifvvjkktvc9upu
Tags: 0.32-1
* Imported Upstream version 0.32
* Remove spelling patch included upstream
* Remove documentation patch, we do not rebuild documentation
* Remove memcached patch, fixed upstream
* Use dh_autoreconf
* Use copyright format 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 *  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
 
#include <config.h>
40
 
#include <libgearman/common.h>
41
 
 
42
 
#include <arpa/inet.h>
43
 
#include <cassert>
44
 
#include <cerrno>
45
 
#include <cstdio>
46
 
#include <cstdlib>
47
 
#include <cstring>
48
 
#include <memory>
49
 
#include <netdb.h>
50
 
#include <netinet/in.h>
51
 
#include <sys/socket.h>
52
 
#include <poll.h>
53
 
 
54
 
/*
55
 
  Allocate a client structure.
56
 
 */
57
 
static gearman_client_st *_client_allocate(gearman_client_st *client, bool is_clone)
58
 
{
59
 
  if (client)
60
 
  {
61
 
    client->options.allocated= false;
62
 
  }
63
 
  else
64
 
  {
65
 
    client= new (std::nothrow) gearman_client_st;
66
 
    if (client == NULL)
67
 
      return NULL;
68
 
 
69
 
    client->options.allocated= true;
70
 
  }
71
 
 
72
 
  client->options.non_blocking= false;
73
 
  client->options.unbuffered_result= false;
74
 
  client->options.no_new= false;
75
 
  client->options.free_tasks= false;
76
 
 
77
 
  client->state= GEARMAN_CLIENT_STATE_IDLE;
78
 
  client->new_tasks= 0;
79
 
  client->running_tasks= 0;
80
 
  client->task_count= 0;
81
 
  client->context= NULL;
82
 
  client->con= NULL;
83
 
  client->task= NULL;
84
 
  client->task_list= NULL;
85
 
  client->task_context_free_fn= NULL;
86
 
  gearman_client_clear_fn(client);
87
 
 
88
 
  if (not is_clone)
89
 
  {
90
 
    gearman_universal_initialize(client->universal);
91
 
  }
92
 
 
93
 
  return client;
94
 
}
95
 
 
96
 
/**
97
 
 * Callback function used when parsing server lists.
98
 
 */
99
 
static gearman_return_t _client_add_server(const char *host, in_port_t port,
100
 
                                           void *context)
101
 
{
102
 
  return gearman_client_add_server(static_cast<gearman_client_st *>(context), host, port);
103
 
}
104
 
 
105
 
 
106
 
/**
107
 
 * Real do function.
108
 
 */
109
 
static void *_client_do(gearman_client_st *client, gearman_command_t command,
110
 
                        const char *function_name,
111
 
                        const char *unique,
112
 
                        const void *workload_str, size_t workload_size,
113
 
                        size_t *result_size, gearman_return_t *ret_ptr)
114
 
{
115
 
  gearman_return_t unused;
116
 
  if (ret_ptr == NULL)
117
 
  {
118
 
    ret_ptr= &unused;
119
 
  }
120
 
 
121
 
  universal_reset_error(client->universal);
122
 
 
123
 
  size_t unused_size;
124
 
  if (result_size == NULL)
125
 
  {
126
 
    result_size= &unused_size;
127
 
  }
128
 
  *result_size= 0;
129
 
 
130
 
  if (client == NULL)
131
 
  {
132
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
133
 
    return NULL;
134
 
  }
135
 
 
136
 
  gearman_string_t function= { gearman_string_param_cstr(function_name) };
137
 
  gearman_unique_t local_unique= gearman_unique_make(unique, unique ? strlen(unique) : 0);
138
 
  gearman_string_t workload= { static_cast<const char*>(workload_str), workload_size };
139
 
 
140
 
 
141
 
  gearman_task_st do_task;
142
 
  gearman_task_st *do_task_ptr= add_task(*client, &do_task, NULL, command,
143
 
                                         function,
144
 
                                         local_unique,
145
 
                                         workload,
146
 
                                         time_t(0),
147
 
                                         gearman_actions_do_default());
148
 
  if (do_task_ptr == NULL)
149
 
  {
150
 
    *ret_ptr= gearman_universal_error_code(client->universal);
151
 
    return NULL;
152
 
  }
153
 
  do_task_ptr->type= GEARMAN_TASK_KIND_DO;
154
 
 
155
 
  gearman_return_t ret;
156
 
  do {
157
 
    ret= gearman_client_run_tasks(client);
158
 
  } while (gearman_continue(ret));
159
 
 
160
 
  // gearman_client_run_tasks failed
161
 
  assert(client->task_list); // Programmer error, we should always have the task that we used for do
162
 
 
163
 
  char *returnable= NULL;
164
 
  if (gearman_failed(ret))
165
 
  {
166
 
    if (ret == GEARMAN_COULD_NOT_CONNECT)
167
 
    { }
168
 
    else
169
 
    {
170
 
      gearman_error(client->universal, ret, "occured during gearman_client_run_tasks()");
171
 
    }
172
 
 
173
 
    *ret_ptr= ret;
174
 
    *result_size= 0;
175
 
  }
176
 
  else if (gearman_success(ret) and do_task_ptr->result_rc == GEARMAN_SUCCESS)
177
 
  {
178
 
    *ret_ptr= do_task_ptr->result_rc;
179
 
    if (do_task_ptr->result_ptr)
180
 
    {
181
 
      if (gearman_has_allocator(client->universal))
182
 
      {
183
 
        gearman_string_t result= gearman_result_string(do_task_ptr->result_ptr);
184
 
        returnable= static_cast<char *>(gearman_malloc(client->universal, gearman_size(result) +1));
185
 
        if (not returnable)
186
 
        {
187
 
          gearman_error(client->universal, GEARMAN_MEMORY_ALLOCATION_FAILURE, "custom workload_fn failed to allocate memory");
188
 
          *result_size= 0;
189
 
        }
190
 
        else // NULL terminate
191
 
        {
192
 
          memcpy(returnable, gearman_c_str(result), gearman_size(result));
193
 
          returnable[gearman_size(result)]= 0;
194
 
          *result_size= gearman_size(result);
195
 
        }
196
 
      }
197
 
      else
198
 
      {
199
 
        gearman_string_t result= gearman_result_take_string(do_task_ptr->result_ptr);
200
 
        *result_size= gearman_size(result);
201
 
        returnable= const_cast<char *>(gearman_c_str(result));
202
 
      }
203
 
    }
204
 
    else // NULL job
205
 
    {
206
 
      *result_size= 0;
207
 
    }
208
 
  }
209
 
  else // gearman_client_run_tasks() was successful, but the task was not
210
 
  {
211
 
    gearman_error(client->universal, do_task_ptr->result_rc, "occured during gearman_client_run_tasks()");
212
 
 
213
 
    *ret_ptr= do_task_ptr->result_rc;
214
 
    *result_size= 0;
215
 
  }
216
 
 
217
 
  gearman_task_free(&do_task);
218
 
  client->new_tasks= 0;
219
 
  client->running_tasks= 0;
220
 
 
221
 
  return returnable;
222
 
}
223
 
 
224
 
/*
225
 
  Real background do function.
226
 
*/
227
 
static gearman_return_t _client_do_background(gearman_client_st *client,
228
 
                                              gearman_command_t command,
229
 
                                              gearman_string_t &function,
230
 
                                              gearman_unique_t &unique,
231
 
                                              gearman_string_t &workload,
232
 
                                              gearman_job_handle_t job_handle)
233
 
{
234
 
  if (client == NULL)
235
 
  {
236
 
    return GEARMAN_INVALID_ARGUMENT;
237
 
  }
238
 
 
239
 
  universal_reset_error(client->universal);
240
 
 
241
 
  if (gearman_size(function) == 0)
242
 
  {
243
 
    return gearman_error(client->universal, GEARMAN_INVALID_ARGUMENT, "function arguement was empty");
244
 
  }
245
 
 
246
 
  client->_do_handle[0]= 0; // Reset the job_handle we store in client
247
 
 
248
 
  gearman_task_st do_task, *do_task_ptr;
249
 
  do_task_ptr= add_task(*client, &do_task, 
250
 
                        client, 
251
 
                        command,
252
 
                        function,
253
 
                        unique,
254
 
                        workload,
255
 
                        time_t(0),
256
 
                        gearman_actions_do_default());
257
 
  if (not do_task_ptr)
258
 
  {
259
 
    return gearman_universal_error_code(client->universal);
260
 
  }
261
 
  do_task_ptr->type= GEARMAN_TASK_KIND_DO;
262
 
 
263
 
  gearman_return_t ret;
264
 
  do {
265
 
    ret= gearman_client_run_tasks(client);
266
 
    
267
 
    // If either of the following is ever true, we will end up in an
268
 
    // infinite loop
269
 
    assert(ret != GEARMAN_IN_PROGRESS and ret != GEARMAN_JOB_EXISTS);
270
 
 
271
 
  } while (gearman_continue(ret));
272
 
 
273
 
  if (job_handle)
274
 
  {
275
 
    strncpy(job_handle, do_task.job_handle, GEARMAN_JOB_HANDLE_SIZE);
276
 
  }
277
 
  strncpy(client->_do_handle, do_task.job_handle, GEARMAN_JOB_HANDLE_SIZE);
278
 
  client->new_tasks= 0;
279
 
  client->running_tasks= 0;
280
 
  gearman_task_free(&do_task);
281
 
 
282
 
  return ret;
283
 
}
284
 
 
285
 
 
286
 
/*
287
 
 * Public Definitions
288
 
 */
289
 
 
290
 
gearman_client_st *gearman_client_create(gearman_client_st *client)
291
 
{
292
 
  return _client_allocate(client, false);
293
 
}
294
 
 
295
 
gearman_client_st *gearman_client_clone(gearman_client_st *client,
296
 
                                        const gearman_client_st *from)
297
 
{
298
 
  if (not from)
299
 
  {
300
 
    return _client_allocate(client, false);
301
 
  }
302
 
 
303
 
  client= _client_allocate(client, true);
304
 
 
305
 
  if (client == NULL)
306
 
  {
307
 
    return client;
308
 
  }
309
 
 
310
 
  client->options.non_blocking= from->options.non_blocking;
311
 
  client->options.unbuffered_result= from->options.unbuffered_result;
312
 
  client->options.no_new= from->options.no_new;
313
 
  client->options.free_tasks= from->options.free_tasks;
314
 
  client->actions= from->actions;
315
 
  client->_do_handle[0]= 0;
316
 
 
317
 
  gearman_universal_clone(client->universal, from->universal);
318
 
 
319
 
  return client;
320
 
}
321
 
 
322
 
void gearman_client_free(gearman_client_st *client)
323
 
{
324
 
  if (client == NULL)
325
 
  {
326
 
    return;
327
 
  }
328
 
 
329
 
  gearman_client_task_free_all(client);
330
 
 
331
 
  gearman_universal_free(client->universal);
332
 
 
333
 
  if (client->options.allocated)
334
 
  {
335
 
    delete client;
336
 
  }
337
 
}
338
 
 
339
 
const char *gearman_client_error(const gearman_client_st *client)
340
 
{
341
 
  if (client == NULL)
342
 
  {
343
 
    return NULL;
344
 
  }
345
 
 
346
 
  return gearman_universal_error(client->universal);
347
 
}
348
 
 
349
 
int gearman_client_errno(const gearman_client_st *client)
350
 
{
351
 
  if (client == NULL)
352
 
  {
353
 
    return 0;
354
 
  }
355
 
 
356
 
  return gearman_universal_errno(client->universal);
357
 
}
358
 
 
359
 
gearman_client_options_t gearman_client_options(const gearman_client_st *client)
360
 
{
361
 
  int32_t options;
362
 
  memset(&options, 0, sizeof(int32_t));
363
 
 
364
 
  if (client->options.allocated)
365
 
    options|= int(GEARMAN_CLIENT_ALLOCATED);
366
 
 
367
 
  if (client->options.non_blocking)
368
 
    options|= int(GEARMAN_CLIENT_NON_BLOCKING);
369
 
 
370
 
  if (client->options.unbuffered_result)
371
 
    options|= int(GEARMAN_CLIENT_UNBUFFERED_RESULT);
372
 
 
373
 
  if (client->options.no_new)
374
 
    options|= int(GEARMAN_CLIENT_NO_NEW);
375
 
 
376
 
  if (client->options.free_tasks)
377
 
    options|= int(GEARMAN_CLIENT_FREE_TASKS);
378
 
 
379
 
  return gearman_client_options_t(options);
380
 
}
381
 
 
382
 
bool gearman_client_has_option(gearman_client_st *client,
383
 
                                gearman_client_options_t option)
384
 
{
385
 
  if (client == NULL)
386
 
    return false;
387
 
 
388
 
  switch (option)
389
 
  {
390
 
  case GEARMAN_CLIENT_ALLOCATED:
391
 
    return client->options.allocated;
392
 
 
393
 
  case GEARMAN_CLIENT_NON_BLOCKING:
394
 
    return client->options.non_blocking;
395
 
 
396
 
  case GEARMAN_CLIENT_UNBUFFERED_RESULT:
397
 
    return client->options.unbuffered_result;
398
 
 
399
 
  case GEARMAN_CLIENT_NO_NEW:
400
 
    return client->options.no_new;
401
 
 
402
 
  case GEARMAN_CLIENT_FREE_TASKS:
403
 
    return client->options.free_tasks;
404
 
 
405
 
  default:
406
 
  case GEARMAN_CLIENT_TASK_IN_USE:
407
 
  case GEARMAN_CLIENT_MAX:
408
 
        return false;
409
 
  }
410
 
}
411
 
 
412
 
void gearman_client_set_options(gearman_client_st *client,
413
 
                                gearman_client_options_t options)
414
 
{
415
 
  if (client == NULL)
416
 
    return;
417
 
 
418
 
  gearman_client_options_t usable_options[]= {
419
 
    GEARMAN_CLIENT_NON_BLOCKING,
420
 
    GEARMAN_CLIENT_UNBUFFERED_RESULT,
421
 
    GEARMAN_CLIENT_FREE_TASKS,
422
 
    GEARMAN_CLIENT_MAX
423
 
  };
424
 
 
425
 
  gearman_client_options_t *ptr;
426
 
 
427
 
 
428
 
  for (ptr= usable_options; *ptr != GEARMAN_CLIENT_MAX ; ptr++)
429
 
  {
430
 
    if (options & *ptr)
431
 
    {
432
 
      gearman_client_add_options(client, *ptr);
433
 
    }
434
 
    else
435
 
    {
436
 
      gearman_client_remove_options(client, *ptr);
437
 
    }
438
 
  }
439
 
}
440
 
 
441
 
void gearman_client_add_options(gearman_client_st *client,
442
 
                                gearman_client_options_t options)
443
 
{
444
 
  if (client == NULL)
445
 
    return;
446
 
 
447
 
  if (options & GEARMAN_CLIENT_NON_BLOCKING)
448
 
  {
449
 
    gearman_universal_add_options(client->universal, GEARMAN_NON_BLOCKING);
450
 
    client->options.non_blocking= true;
451
 
  }
452
 
 
453
 
  if (options & GEARMAN_CLIENT_UNBUFFERED_RESULT)
454
 
  {
455
 
    client->options.unbuffered_result= true;
456
 
  }
457
 
 
458
 
  if (options & GEARMAN_CLIENT_FREE_TASKS)
459
 
  {
460
 
    client->options.free_tasks= true;
461
 
  }
462
 
}
463
 
 
464
 
void gearman_client_remove_options(gearman_client_st *client,
465
 
                                   gearman_client_options_t options)
466
 
{
467
 
  if (client == NULL)
468
 
    return;
469
 
 
470
 
  if (options & GEARMAN_CLIENT_NON_BLOCKING)
471
 
  {
472
 
    gearman_universal_remove_options(client->universal, GEARMAN_NON_BLOCKING);
473
 
    client->options.non_blocking= false;
474
 
  }
475
 
 
476
 
  if (options & GEARMAN_CLIENT_UNBUFFERED_RESULT)
477
 
  {
478
 
    client->options.unbuffered_result= false;
479
 
  }
480
 
 
481
 
  if (options & GEARMAN_CLIENT_FREE_TASKS)
482
 
  {
483
 
    client->options.free_tasks= false;
484
 
  }
485
 
}
486
 
 
487
 
int gearman_client_timeout(gearman_client_st *client)
488
 
{
489
 
  return gearman_universal_timeout(client->universal);
490
 
}
491
 
 
492
 
void gearman_client_set_timeout(gearman_client_st *client, int timeout)
493
 
{
494
 
  if (client == NULL)
495
 
    return;
496
 
 
497
 
  gearman_universal_set_timeout(client->universal, timeout);
498
 
}
499
 
 
500
 
void *gearman_client_context(const gearman_client_st *client)
501
 
{
502
 
  if (client == NULL)
503
 
    return NULL;
504
 
 
505
 
  return const_cast<void *>(client->context);
506
 
}
507
 
 
508
 
void gearman_client_set_context(gearman_client_st *client, void *context)
509
 
{
510
 
  if (client == NULL)
511
 
    return;
512
 
 
513
 
  client->context= context;
514
 
}
515
 
 
516
 
void gearman_client_set_log_fn(gearman_client_st *client,
517
 
                               gearman_log_fn *function, void *context,
518
 
                               gearman_verbose_t verbose)
519
 
{
520
 
  if (client == NULL)
521
 
    return;
522
 
 
523
 
  gearman_set_log_fn(client->universal, function, context, verbose);
524
 
}
525
 
 
526
 
void gearman_client_set_workload_malloc_fn(gearman_client_st *client,
527
 
                                           gearman_malloc_fn *function,
528
 
                                           void *context)
529
 
{
530
 
  if (client == NULL)
531
 
    return;
532
 
 
533
 
  gearman_set_workload_malloc_fn(client->universal, function, context);
534
 
}
535
 
 
536
 
void gearman_client_set_workload_free_fn(gearman_client_st *client, gearman_free_fn *function, void *context)
537
 
{
538
 
  if (client == NULL)
539
 
    return;
540
 
 
541
 
  gearman_set_workload_free_fn(client->universal, function, context);
542
 
}
543
 
 
544
 
gearman_return_t gearman_client_add_server(gearman_client_st *client,
545
 
                                           const char *host, in_port_t port)
546
 
{
547
 
  if (client == NULL)
548
 
  {
549
 
    return GEARMAN_INVALID_ARGUMENT;
550
 
  }
551
 
 
552
 
  if (gearman_connection_create_args(client->universal, host, port) == false)
553
 
  {
554
 
    assert(client->universal.error.rc != GEARMAN_SUCCESS);
555
 
    return gearman_universal_error_code(client->universal);
556
 
  }
557
 
 
558
 
  return GEARMAN_SUCCESS;
559
 
}
560
 
 
561
 
gearman_return_t gearman_client_add_servers(gearman_client_st *client,
562
 
                                            const char *servers)
563
 
{
564
 
  return gearman_parse_servers(servers, _client_add_server, client);
565
 
}
566
 
 
567
 
void gearman_client_remove_servers(gearman_client_st *client)
568
 
{
569
 
  if (client == NULL)
570
 
  {
571
 
    return;
572
 
  }
573
 
 
574
 
  gearman_free_all_cons(client->universal);
575
 
}
576
 
 
577
 
gearman_return_t gearman_client_wait(gearman_client_st *client)
578
 
{
579
 
  if (client == NULL)
580
 
  {
581
 
    return GEARMAN_INVALID_ARGUMENT;
582
 
  }
583
 
 
584
 
  return gearman_wait(client->universal);
585
 
}
586
 
 
587
 
void *gearman_client_do(gearman_client_st *client,
588
 
                        const char *function,
589
 
                        const char *unique,
590
 
                        const void *workload,
591
 
                        size_t workload_size, size_t *result_size,
592
 
                        gearman_return_t *ret_ptr)
593
 
{
594
 
  return _client_do(client, GEARMAN_COMMAND_SUBMIT_JOB,
595
 
                    function,
596
 
                    unique,
597
 
                    workload, workload_size,
598
 
                    result_size, ret_ptr);
599
 
}
600
 
 
601
 
void *gearman_client_do_high(gearman_client_st *client,
602
 
                             const char *function,
603
 
                             const char *unique,
604
 
                             const void *workload, size_t workload_size,
605
 
                             size_t *result_size, gearman_return_t *ret_ptr)
606
 
{
607
 
  return _client_do(client, GEARMAN_COMMAND_SUBMIT_JOB_HIGH,
608
 
                    function,
609
 
                    unique,
610
 
                    workload, workload_size,
611
 
                    result_size, ret_ptr);
612
 
}
613
 
 
614
 
void *gearman_client_do_low(gearman_client_st *client,
615
 
                            const char *function,
616
 
                            const char *unique,
617
 
                            const void *workload, size_t workload_size,
618
 
                            size_t *result_size, gearman_return_t *ret_ptr)
619
 
{
620
 
  return _client_do(client, GEARMAN_COMMAND_SUBMIT_JOB_LOW,
621
 
                    function,
622
 
                    unique,
623
 
                    workload, workload_size,
624
 
                    result_size, ret_ptr);
625
 
}
626
 
 
627
 
size_t gearman_client_count_tasks(gearman_client_st *client)
628
 
{
629
 
  if (client == NULL)
630
 
  {
631
 
    return 0;
632
 
  }
633
 
 
634
 
  size_t count= 1;
635
 
  gearman_task_st *search= client->task_list;
636
 
 
637
 
  while ((search= search->next))
638
 
  {
639
 
    count++;
640
 
  }
641
 
 
642
 
  return count;
643
 
}
644
 
 
645
 
#if 0
646
 
static bool _active_tasks(gearman_client_st *client)
647
 
{
648
 
  assert(client);
649
 
  gearman_task_st *search= client->task_list;
650
 
 
651
 
  if (not search)
652
 
    return false;
653
 
 
654
 
  do
655
 
  {
656
 
    if (gearman_task_is_active(search))
657
 
    {
658
 
      return true;
659
 
    }
660
 
  } while ((search= search->next));
661
 
 
662
 
  return false;
663
 
}
664
 
#endif
665
 
 
666
 
const char *gearman_client_do_job_handle(gearman_client_st *self)
667
 
{
668
 
  if (self == NULL)
669
 
  {
670
 
    errno= EINVAL;
671
 
    return NULL;
672
 
  }
673
 
 
674
 
  return self->_do_handle;
675
 
}
676
 
 
677
 
void gearman_client_do_status(gearman_client_st *, uint32_t *numerator, uint32_t *denominator)
678
 
{
679
 
  if (numerator)
680
 
    *numerator= 0;
681
 
 
682
 
  if (denominator)
683
 
    *denominator= 0;
684
 
}
685
 
 
686
 
gearman_return_t gearman_client_do_background(gearman_client_st *client,
687
 
                                              const char *function_name,
688
 
                                              const char *unique,
689
 
                                              const void *workload_str,
690
 
                                              size_t workload_size,
691
 
                                              gearman_job_handle_t job_handle)
692
 
{
693
 
  gearman_string_t function= { gearman_string_param_cstr(function_name) };
694
 
  gearman_unique_t local_unique= gearman_unique_make(unique, unique ? strlen(unique) : 0);
695
 
  gearman_string_t workload= { static_cast<const char*>(workload_str), workload_size };
696
 
 
697
 
  return _client_do_background(client, GEARMAN_COMMAND_SUBMIT_JOB_BG,
698
 
                               function,
699
 
                               local_unique,
700
 
                               workload,
701
 
                               job_handle);
702
 
}
703
 
 
704
 
gearman_return_t gearman_client_do_high_background(gearman_client_st *client,
705
 
                                                   const char *function_name,
706
 
                                                   const char *unique,
707
 
                                                   const void *workload_str,
708
 
                                                   size_t workload_size,
709
 
                                                   gearman_job_handle_t job_handle)
710
 
{
711
 
  gearman_string_t function= { gearman_string_param_cstr(function_name) };
712
 
  gearman_unique_t local_unique= gearman_unique_make(unique, unique ? strlen(unique) : 0);
713
 
  gearman_string_t workload= { static_cast<const char*>(workload_str), workload_size };
714
 
 
715
 
  return _client_do_background(client, GEARMAN_COMMAND_SUBMIT_JOB_HIGH_BG,
716
 
                               function,
717
 
                               local_unique,
718
 
                               workload,
719
 
                               job_handle);
720
 
}
721
 
 
722
 
gearman_return_t gearman_client_do_low_background(gearman_client_st *client,
723
 
                                                  const char *function_name,
724
 
                                                  const char *unique,
725
 
                                                  const void *workload_str,
726
 
                                                  size_t workload_size,
727
 
                                                  gearman_job_handle_t job_handle)
728
 
{
729
 
  gearman_string_t function= { gearman_string_param_cstr(function_name) };
730
 
  gearman_unique_t local_unique= gearman_unique_make(unique, unique ? strlen(unique) : 0);
731
 
  gearman_string_t workload= { static_cast<const char*>(workload_str), workload_size };
732
 
 
733
 
  return _client_do_background(client, GEARMAN_COMMAND_SUBMIT_JOB_LOW_BG,
734
 
                               function,
735
 
                               local_unique,
736
 
                               workload,
737
 
                               job_handle);
738
 
}
739
 
 
740
 
gearman_return_t gearman_client_job_status(gearman_client_st *client,
741
 
                                           const gearman_job_handle_t job_handle,
742
 
                                           bool *is_known, bool *is_running,
743
 
                                           uint32_t *numerator,
744
 
                                           uint32_t *denominator)
745
 
{
746
 
  gearman_return_t ret;
747
 
 
748
 
  if (client == NULL)
749
 
  {
750
 
    return GEARMAN_INVALID_ARGUMENT;
751
 
  }
752
 
 
753
 
  universal_reset_error(client->universal);
754
 
 
755
 
  gearman_task_st do_task;
756
 
  gearman_task_st *do_task_ptr= gearman_client_add_task_status(client, &do_task, client,
757
 
                                                               job_handle, &ret);
758
 
  if (gearman_failed(ret))
759
 
  {
760
 
    return ret;
761
 
  }
762
 
  assert(do_task_ptr);
763
 
  do_task_ptr->type= GEARMAN_TASK_KIND_DO;
764
 
 
765
 
  gearman_task_clear_fn(do_task_ptr);
766
 
 
767
 
  do {
768
 
    ret= gearman_client_run_tasks(client);
769
 
    
770
 
    // If either of the following is ever true, we will end up in an
771
 
    // infinite loop
772
 
    assert(ret != GEARMAN_IN_PROGRESS and ret != GEARMAN_JOB_EXISTS);
773
 
 
774
 
  } while (gearman_continue(ret));
775
 
 
776
 
  // @note we don't know if our task was run or not, we just know something
777
 
  // happened.
778
 
 
779
 
  if (gearman_success(ret))
780
 
  {
781
 
    if (is_known)
782
 
      *is_known= do_task.options.is_known;
783
 
 
784
 
    if (is_running)
785
 
      *is_running= do_task.options.is_running;
786
 
 
787
 
    if (numerator)
788
 
      *numerator= do_task.numerator;
789
 
 
790
 
    if (denominator)
791
 
      *denominator= do_task.denominator;
792
 
 
793
 
    if (not is_known and not is_running)
794
 
    {
795
 
      if (do_task.options.is_running) 
796
 
      {
797
 
        ret= GEARMAN_IN_PROGRESS;
798
 
      }
799
 
      else if (do_task.options.is_known)
800
 
      {
801
 
        ret= GEARMAN_JOB_EXISTS;
802
 
      }
803
 
    }
804
 
  }
805
 
  else
806
 
  {
807
 
    if (is_known)
808
 
    {
809
 
      *is_known= false;
810
 
    }
811
 
 
812
 
    if (is_running)
813
 
      *is_running= false;
814
 
 
815
 
    if (numerator)
816
 
      *numerator= 0;
817
 
 
818
 
    if (denominator)
819
 
      *denominator= 0;
820
 
  }
821
 
  gearman_task_free(do_task_ptr);
822
 
 
823
 
  return ret;
824
 
}
825
 
 
826
 
gearman_return_t gearman_client_echo(gearman_client_st *client,
827
 
                                     const void *workload,
828
 
                                     size_t workload_size)
829
 
{
830
 
  if (client == NULL)
831
 
  {
832
 
    return GEARMAN_INVALID_ARGUMENT;
833
 
  }
834
 
 
835
 
  return gearman_echo(client->universal, workload, workload_size);
836
 
}
837
 
 
838
 
void gearman_client_task_free_all(gearman_client_st *client)
839
 
{
840
 
  if (client == NULL)
841
 
  {
842
 
    return;
843
 
  }
844
 
 
845
 
  while (client->task_list)
846
 
  {
847
 
    gearman_task_free(client->task_list);
848
 
  }
849
 
}
850
 
 
851
 
void gearman_client_set_task_context_free_fn(gearman_client_st *client,
852
 
                                             gearman_task_context_free_fn *function)
853
 
{
854
 
  if (client == NULL)
855
 
  {
856
 
    return;
857
 
  }
858
 
 
859
 
  client->task_context_free_fn= function;
860
 
 
861
 
}
862
 
 
863
 
gearman_return_t gearman_client_set_memory_allocators(gearman_client_st *client,
864
 
                                                      gearman_malloc_fn *malloc_fn,
865
 
                                                      gearman_free_fn *free_fn,
866
 
                                                      gearman_realloc_fn *realloc_fn,
867
 
                                                      gearman_calloc_fn *calloc_fn,
868
 
                                                      void *context)
869
 
{
870
 
  if (client == NULL)
871
 
  {
872
 
    return GEARMAN_INVALID_ARGUMENT;
873
 
  }
874
 
 
875
 
  return gearman_set_memory_allocator(client->universal.allocator, malloc_fn, free_fn, realloc_fn, calloc_fn, context);
876
 
}
877
 
 
878
 
 
879
 
 
880
 
gearman_task_st *gearman_client_add_task(gearman_client_st *client,
881
 
                                         gearman_task_st *task,
882
 
                                         void *context,
883
 
                                         const char *function,
884
 
                                         const char *unique,
885
 
                                         const void *workload, size_t workload_size,
886
 
                                         gearman_return_t *ret_ptr)
887
 
{
888
 
  gearman_return_t unused;
889
 
  if (ret_ptr == NULL)
890
 
  {
891
 
    ret_ptr= &unused;
892
 
  }
893
 
 
894
 
  if (client == NULL)
895
 
  {
896
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
897
 
    return NULL;
898
 
  }
899
 
 
900
 
  return add_task(*client, task,
901
 
                  context, GEARMAN_COMMAND_SUBMIT_JOB,
902
 
                  function,
903
 
                  unique,
904
 
                  workload, workload_size,
905
 
                  time_t(0),
906
 
                  ret_ptr,
907
 
                  client->actions);
908
 
}
909
 
 
910
 
gearman_task_st *gearman_client_add_task_high(gearman_client_st *client,
911
 
                                              gearman_task_st *task,
912
 
                                              void *context,
913
 
                                              const char *function,
914
 
                                              const char *unique,
915
 
                                              const void *workload, size_t workload_size,
916
 
                                              gearman_return_t *ret_ptr)
917
 
{
918
 
  gearman_return_t unused;
919
 
  if (ret_ptr == NULL)
920
 
  {
921
 
    ret_ptr= &unused;
922
 
  }
923
 
 
924
 
  if (client == NULL)
925
 
  {
926
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
927
 
    return NULL;
928
 
  }
929
 
 
930
 
  return add_task(*client, task, context,
931
 
                  GEARMAN_COMMAND_SUBMIT_JOB_HIGH,
932
 
                  function,
933
 
                  unique,
934
 
                  workload, workload_size,
935
 
                  time_t(0),
936
 
                  ret_ptr,
937
 
                  client->actions);
938
 
}
939
 
 
940
 
gearman_task_st *gearman_client_add_task_low(gearman_client_st *client,
941
 
                                             gearman_task_st *task,
942
 
                                             void *context,
943
 
                                             const char *function,
944
 
                                             const char *unique,
945
 
                                             const void *workload, size_t workload_size,
946
 
                                             gearman_return_t *ret_ptr)
947
 
{
948
 
  gearman_return_t unused;
949
 
  if (ret_ptr == NULL)
950
 
  {
951
 
    ret_ptr= &unused;
952
 
  }
953
 
 
954
 
  if (client == NULL)
955
 
  {
956
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
957
 
    return NULL;
958
 
  }
959
 
 
960
 
  return add_task(*client, task, context, GEARMAN_COMMAND_SUBMIT_JOB_LOW,
961
 
                  function,
962
 
                  unique,
963
 
                  workload, workload_size,
964
 
                  time_t(0),
965
 
                  ret_ptr,
966
 
                  client->actions);
967
 
}
968
 
 
969
 
gearman_task_st *gearman_client_add_task_background(gearman_client_st *client,
970
 
                                                    gearman_task_st *task,
971
 
                                                    void *context,
972
 
                                                    const char *function,
973
 
                                                    const char *unique,
974
 
                                                    const void *workload, size_t workload_size,
975
 
                                                    gearman_return_t *ret_ptr)
976
 
{
977
 
  gearman_return_t unused;
978
 
  if (ret_ptr == NULL)
979
 
  {
980
 
    ret_ptr= &unused;
981
 
  }
982
 
 
983
 
  if (client == NULL)
984
 
  {
985
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
986
 
    return NULL;
987
 
  }
988
 
 
989
 
  return add_task(*client, task, context, GEARMAN_COMMAND_SUBMIT_JOB_BG,
990
 
                  function,
991
 
                  unique,
992
 
                  workload, workload_size,
993
 
                  time_t(0),
994
 
                  ret_ptr,
995
 
                  client->actions);
996
 
}
997
 
 
998
 
gearman_task_st *
999
 
gearman_client_add_task_high_background(gearman_client_st *client,
1000
 
                                        gearman_task_st *task,
1001
 
                                        void *context,
1002
 
                                        const char *function,
1003
 
                                        const char *unique,
1004
 
                                        const void *workload, size_t workload_size,
1005
 
                                        gearman_return_t *ret_ptr)
1006
 
{
1007
 
  gearman_return_t unused;
1008
 
  if (ret_ptr == NULL)
1009
 
  {
1010
 
    ret_ptr= &unused;
1011
 
  }
1012
 
 
1013
 
  if (client == NULL)
1014
 
  {
1015
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
1016
 
    return NULL;
1017
 
  }
1018
 
 
1019
 
  return add_task(*client, task, context,
1020
 
                  GEARMAN_COMMAND_SUBMIT_JOB_HIGH_BG,
1021
 
                  function,
1022
 
                  unique,
1023
 
                  workload, workload_size,
1024
 
                  time_t(0),
1025
 
                  ret_ptr,
1026
 
                  client->actions);
1027
 
}
1028
 
 
1029
 
gearman_task_st *
1030
 
gearman_client_add_task_low_background(gearman_client_st *client,
1031
 
                                       gearman_task_st *task,
1032
 
                                       void *context,
1033
 
                                       const char *function,
1034
 
                                       const char *unique,
1035
 
                                       const void *workload, size_t workload_size,
1036
 
                                       gearman_return_t *ret_ptr)
1037
 
{
1038
 
  gearman_return_t unused;
1039
 
  if (ret_ptr == NULL)
1040
 
  {
1041
 
    ret_ptr= &unused;
1042
 
  }
1043
 
 
1044
 
  if (client == NULL)
1045
 
  {
1046
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
1047
 
    return NULL;
1048
 
  }
1049
 
 
1050
 
  return add_task(*client, task, context,
1051
 
                  GEARMAN_COMMAND_SUBMIT_JOB_LOW_BG,
1052
 
                  function,
1053
 
                  unique,
1054
 
                  workload, workload_size,
1055
 
                  time_t(0),
1056
 
                  ret_ptr,
1057
 
                  client->actions);
1058
 
 
1059
 
}
1060
 
 
1061
 
gearman_task_st *gearman_client_add_task_status(gearman_client_st *client,
1062
 
                                                gearman_task_st *task,
1063
 
                                                void *context,
1064
 
                                                const gearman_job_handle_t job_handle,
1065
 
                                                gearman_return_t *ret_ptr)
1066
 
{
1067
 
  const void *args[1];
1068
 
  size_t args_size[1];
1069
 
 
1070
 
  gearman_return_t unused;
1071
 
  if (ret_ptr == NULL)
1072
 
  {
1073
 
    ret_ptr= &unused;
1074
 
  }
1075
 
 
1076
 
  if (client == NULL)
1077
 
  {
1078
 
    *ret_ptr= GEARMAN_INVALID_ARGUMENT;
1079
 
    return NULL;
1080
 
  }
1081
 
 
1082
 
  if ((task= gearman_task_internal_create(client, task)) == NULL)
1083
 
  {
1084
 
    *ret_ptr= GEARMAN_MEMORY_ALLOCATION_FAILURE;
1085
 
    return NULL;
1086
 
  }
1087
 
 
1088
 
  task->context= context;
1089
 
  snprintf(task->job_handle, GEARMAN_JOB_HANDLE_SIZE, "%s", job_handle);
1090
 
 
1091
 
  args[0]= job_handle;
1092
 
  args_size[0]= strlen(job_handle);
1093
 
  gearman_return_t rc= gearman_packet_create_args(client->universal, task->send,
1094
 
                                                  GEARMAN_MAGIC_REQUEST,
1095
 
                                                  GEARMAN_COMMAND_GET_STATUS,
1096
 
                                                  args, args_size, 1);
1097
 
  if (gearman_success(rc))
1098
 
  {
1099
 
    client->new_tasks++;
1100
 
    client->running_tasks++;
1101
 
    task->options.send_in_use= true;
1102
 
  }
1103
 
  *ret_ptr= rc;
1104
 
 
1105
 
  return task;
1106
 
}
1107
 
 
1108
 
void gearman_client_set_workload_fn(gearman_client_st *client,
1109
 
                                    gearman_workload_fn *function)
1110
 
{
1111
 
  if (client == NULL)
1112
 
  {
1113
 
    return;
1114
 
  }
1115
 
 
1116
 
  client->actions.workload_fn= function;
1117
 
}
1118
 
 
1119
 
void gearman_client_set_created_fn(gearman_client_st *client,
1120
 
                                   gearman_created_fn *function)
1121
 
{
1122
 
  if (client == NULL)
1123
 
  {
1124
 
    return;
1125
 
  }
1126
 
 
1127
 
  client->actions.created_fn= function;
1128
 
}
1129
 
 
1130
 
void gearman_client_set_data_fn(gearman_client_st *client,
1131
 
                                gearman_data_fn *function)
1132
 
{
1133
 
  if (client == NULL)
1134
 
  {
1135
 
    return;
1136
 
  }
1137
 
 
1138
 
  client->actions.data_fn= function;
1139
 
}
1140
 
 
1141
 
void gearman_client_set_warning_fn(gearman_client_st *client,
1142
 
                                   gearman_warning_fn *function)
1143
 
{
1144
 
  if (client == NULL)
1145
 
  {
1146
 
    return;
1147
 
  }
1148
 
 
1149
 
  client->actions.warning_fn= function;
1150
 
}
1151
 
 
1152
 
void gearman_client_set_status_fn(gearman_client_st *client,
1153
 
                                  gearman_universal_status_fn *function)
1154
 
{
1155
 
  if (client == NULL)
1156
 
  {
1157
 
    return;
1158
 
  }
1159
 
 
1160
 
  client->actions.status_fn= function;
1161
 
}
1162
 
 
1163
 
void gearman_client_set_complete_fn(gearman_client_st *client,
1164
 
                                    gearman_complete_fn *function)
1165
 
{
1166
 
  if (client == NULL)
1167
 
  {
1168
 
    return;
1169
 
  }
1170
 
 
1171
 
  client->actions.complete_fn= function;
1172
 
}
1173
 
 
1174
 
void gearman_client_set_exception_fn(gearman_client_st *client,
1175
 
                                     gearman_exception_fn *function)
1176
 
{
1177
 
  if (client == NULL)
1178
 
  {
1179
 
    return;
1180
 
  }
1181
 
 
1182
 
  client->actions.exception_fn= function;
1183
 
}
1184
 
 
1185
 
void gearman_client_set_fail_fn(gearman_client_st *client,
1186
 
                                gearman_fail_fn *function)
1187
 
{
1188
 
  if (client == NULL)
1189
 
  {
1190
 
    return;
1191
 
  }
1192
 
 
1193
 
  client->actions.fail_fn= function;
1194
 
}
1195
 
 
1196
 
void gearman_client_clear_fn(gearman_client_st *client)
1197
 
{
1198
 
  if (client == NULL)
1199
 
  {
1200
 
    return;
1201
 
  }
1202
 
 
1203
 
  client->actions= gearman_actions_default();
1204
 
}
1205
 
 
1206
 
static inline void _push_non_blocking(gearman_client_st *client)
1207
 
{
1208
 
  client->universal.options.stored_non_blocking= client->universal.options.non_blocking;
1209
 
  client->universal.options.non_blocking= true;
1210
 
}
1211
 
 
1212
 
static inline void _pop_non_blocking(gearman_client_st *client)
1213
 
{
1214
 
  client->universal.options.non_blocking= client->options.non_blocking;
1215
 
  assert(client->universal.options.stored_non_blocking == client->options.non_blocking);
1216
 
}
1217
 
 
1218
 
static inline void _push_blocking(gearman_client_st *client)
1219
 
{
1220
 
  client->universal.options.stored_non_blocking= client->universal.options.non_blocking;
1221
 
  client->universal.options.non_blocking= false;
1222
 
}
1223
 
 
1224
 
static inline void _pop_blocking(gearman_client_st *client)
1225
 
{
1226
 
  client->universal.options.non_blocking= client->options.non_blocking;
1227
 
  assert(client->universal.options.stored_non_blocking == client->options.non_blocking);
1228
 
}
1229
 
 
1230
 
static inline gearman_return_t _client_run_tasks(gearman_client_st *client)
1231
 
{
1232
 
  gearman_return_t ret= GEARMAN_MAX_RETURN;
1233
 
 
1234
 
  switch(client->state)
1235
 
  {
1236
 
  case GEARMAN_CLIENT_STATE_IDLE:
1237
 
    while (1)
1238
 
    {
1239
 
      /* Start any new tasks. */
1240
 
      if (client->new_tasks > 0 && ! (client->options.no_new))
1241
 
      {
1242
 
        for (client->task= client->task_list; client->task;
1243
 
             client->task= client->task->next)
1244
 
        {
1245
 
          if (client->task->state != GEARMAN_TASK_STATE_NEW)
1246
 
          {
1247
 
            continue;
1248
 
          }
1249
 
 
1250
 
  case GEARMAN_CLIENT_STATE_NEW:
1251
 
          assert_msg(client == client->task->client, "Programmer error, client and task member client are not the same");
1252
 
          gearman_return_t local_ret= _client_run_task(client->task);
1253
 
          if (gearman_failed(local_ret) and local_ret != GEARMAN_IO_WAIT)
1254
 
          {
1255
 
            client->state= GEARMAN_CLIENT_STATE_NEW;
1256
 
 
1257
 
            return local_ret;
1258
 
          }
1259
 
        }
1260
 
 
1261
 
        if (client->new_tasks == 0)
1262
 
        {
1263
 
          gearman_return_t local_ret= gearman_flush_all(client->universal);
1264
 
          if (gearman_failed(local_ret))
1265
 
          {
1266
 
            return local_ret;
1267
 
          }
1268
 
        }
1269
 
      }
1270
 
 
1271
 
      /* See if there are any connections ready for I/O. */
1272
 
      while ((client->con= gearman_ready(client->universal)))
1273
 
      {
1274
 
        if (client->con->revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
1275
 
        {
1276
 
          /* Socket is ready for writing, continue submitting jobs. */
1277
 
          for (client->task= client->task_list; client->task;
1278
 
               client->task= client->task->next)
1279
 
          {
1280
 
            if (client->task->con != client->con or
1281
 
                (client->task->state != GEARMAN_TASK_STATE_SUBMIT and
1282
 
                 client->task->state != GEARMAN_TASK_STATE_WORKLOAD))
1283
 
            {
1284
 
              continue;
1285
 
            }
1286
 
 
1287
 
  case GEARMAN_CLIENT_STATE_SUBMIT:
1288
 
            assert_msg(client == client->task->client, "Programmer error, client and task member client are not the same");
1289
 
            gearman_return_t local_ret= _client_run_task(client->task);
1290
 
            if (local_ret == GEARMAN_COULD_NOT_CONNECT)
1291
 
            {
1292
 
              client->state= GEARMAN_CLIENT_STATE_IDLE;
1293
 
              return local_ret;
1294
 
            }
1295
 
            else if (gearman_failed(local_ret) and local_ret != GEARMAN_IO_WAIT)
1296
 
            {
1297
 
              client->state= GEARMAN_CLIENT_STATE_SUBMIT;
1298
 
              return local_ret;
1299
 
            }
1300
 
          }
1301
 
        }
1302
 
 
1303
 
        if (not (client->con->revents & POLLIN))
1304
 
          continue;
1305
 
 
1306
 
        /* Socket is ready for reading. */
1307
 
        while (1)
1308
 
        {
1309
 
          /* Read packet on connection and find which task it belongs to. */
1310
 
          if (client->options.unbuffered_result)
1311
 
          {
1312
 
            /* If client is handling the data read, make sure it's complete. */
1313
 
            if (client->con->recv_state == GEARMAN_CON_RECV_STATE_READ_DATA)
1314
 
            {
1315
 
              for (client->task= client->task_list; client->task;
1316
 
                   client->task= client->task->next)
1317
 
              {
1318
 
                if (client->task->con == client->con &&
1319
 
                    (client->task->state == GEARMAN_TASK_STATE_DATA or
1320
 
                     client->task->state == GEARMAN_TASK_STATE_COMPLETE))
1321
 
                {
1322
 
                  break;
1323
 
                }
1324
 
              }
1325
 
 
1326
 
              /*
1327
 
                Someone has set GEARMAN_CLIENT_UNBUFFERED_RESULT but hasn't setup the client to fetch data correctly.
1328
 
                Fatal error :(
1329
 
              */
1330
 
              return gearman_universal_set_error(client->universal, GEARMAN_INVALID_ARGUMENT, GEARMAN_AT,
1331
 
                                                 "client created with GEARMAN_CLIENT_UNBUFFERED_RESULT, but was not setup to use it. %s", __func__);
1332
 
            }
1333
 
            else
1334
 
            {
1335
 
              /* Read the next packet, without buffering the data part. */
1336
 
              client->task= NULL;
1337
 
              (void)client->con->receiving(client->con->_packet, ret, false);
1338
 
            }
1339
 
          }
1340
 
          else
1341
 
          {
1342
 
            /* Read the next packet, buffering the data part. */
1343
 
            client->task= NULL;
1344
 
            (void)client->con->receiving(client->con->_packet, ret, true);
1345
 
          }
1346
 
 
1347
 
          if (client->task == NULL)
1348
 
          {
1349
 
            assert(ret != GEARMAN_MAX_RETURN);
1350
 
 
1351
 
            /* Check the return of the gearman_connection_recv() calls above. */
1352
 
            if (gearman_failed(ret))
1353
 
            {
1354
 
              if (ret == GEARMAN_IO_WAIT)
1355
 
                break;
1356
 
 
1357
 
              client->state= GEARMAN_CLIENT_STATE_IDLE;
1358
 
              return ret;
1359
 
            }
1360
 
 
1361
 
            client->con->options.packet_in_use= true;
1362
 
 
1363
 
            /* We have a packet, see which task it belongs to. */
1364
 
            for (client->task= client->task_list; client->task;
1365
 
                 client->task= client->task->next)
1366
 
            {
1367
 
              if (client->task->con != client->con)
1368
 
                continue;
1369
 
 
1370
 
              if (client->con->_packet.command == GEARMAN_COMMAND_JOB_CREATED)
1371
 
              {
1372
 
                if (client->task->created_id != client->con->created_id)
1373
 
                  continue;
1374
 
 
1375
 
                /* New job created, drop through below and notify task. */
1376
 
                client->con->created_id++;
1377
 
              }
1378
 
              else if (client->con->_packet.command == GEARMAN_COMMAND_ERROR)
1379
 
              {
1380
 
                gearman_universal_set_error(client->universal, GEARMAN_SERVER_ERROR, GEARMAN_AT,
1381
 
                                            "%s:%.*s",
1382
 
                                            static_cast<char *>(client->con->_packet.arg[0]),
1383
 
                                            int(client->con->_packet.arg_size[1]),
1384
 
                                            static_cast<char *>(client->con->_packet.arg[1]));
1385
 
 
1386
 
                return GEARMAN_SERVER_ERROR;
1387
 
              }
1388
 
              else if (strncmp(client->task->job_handle,
1389
 
                               static_cast<char *>(client->con->_packet.arg[0]),
1390
 
                               client->con->_packet.arg_size[0]) ||
1391
 
                       (client->con->_packet.command != GEARMAN_COMMAND_WORK_FAIL &&
1392
 
                        strlen(client->task->job_handle) != client->con->_packet.arg_size[0] - 1) ||
1393
 
                       (client->con->_packet.command == GEARMAN_COMMAND_WORK_FAIL &&
1394
 
                        strlen(client->task->job_handle) != client->con->_packet.arg_size[0]))
1395
 
              {
1396
 
                continue;
1397
 
              }
1398
 
 
1399
 
              /* Else, we have a matching result packet of some kind. */
1400
 
 
1401
 
              break;
1402
 
            }
1403
 
 
1404
 
            if (not client->task)
1405
 
            {
1406
 
              /* The client has stopped waiting for the response, ignore it. */
1407
 
              client->con->free_private_packet();
1408
 
              continue;
1409
 
            }
1410
 
 
1411
 
            client->task->recv= &(client->con->_packet);
1412
 
          }
1413
 
 
1414
 
  case GEARMAN_CLIENT_STATE_PACKET:
1415
 
          /* Let task process job created or result packet. */
1416
 
          assert_msg(client == client->task->client, "Programmer error, client and task member client are not the same");
1417
 
          gearman_return_t local_ret= _client_run_task(client->task);
1418
 
 
1419
 
          if (local_ret == GEARMAN_IO_WAIT)
1420
 
            break;
1421
 
 
1422
 
          if (gearman_failed(local_ret))
1423
 
          {
1424
 
            client->state= GEARMAN_CLIENT_STATE_PACKET;
1425
 
            return local_ret;
1426
 
          }
1427
 
 
1428
 
          /* Clean up the packet. */
1429
 
          client->con->free_private_packet();
1430
 
 
1431
 
          /* If all tasks are done, return. */
1432
 
          if (client->running_tasks == 0)
1433
 
            break;
1434
 
        }
1435
 
      }
1436
 
 
1437
 
      /* If all tasks are done, return. */
1438
 
      if (client->running_tasks == 0)
1439
 
      {
1440
 
        break;
1441
 
      }
1442
 
 
1443
 
      if (client->new_tasks > 0 && ! (client->options.no_new))
1444
 
        continue;
1445
 
 
1446
 
      if (client->options.non_blocking)
1447
 
      {
1448
 
        /* Let the caller wait for activity. */
1449
 
        client->state= GEARMAN_CLIENT_STATE_IDLE;
1450
 
        gearman_gerror(client->universal, GEARMAN_IO_WAIT);
1451
 
 
1452
 
        return GEARMAN_IO_WAIT;
1453
 
      }
1454
 
 
1455
 
      /* Wait for activity on one of the connections. */
1456
 
      gearman_return_t local_ret= gearman_wait(client->universal);
1457
 
      if (gearman_failed(local_ret) and local_ret != GEARMAN_IO_WAIT)
1458
 
      {
1459
 
        client->state= GEARMAN_CLIENT_STATE_IDLE;
1460
 
 
1461
 
        return local_ret;
1462
 
      }
1463
 
    }
1464
 
 
1465
 
    break;
1466
 
  }
1467
 
 
1468
 
  client->state= GEARMAN_CLIENT_STATE_IDLE;
1469
 
 
1470
 
  return GEARMAN_SUCCESS;
1471
 
}
1472
 
 
1473
 
gearman_return_t gearman_client_run_tasks(gearman_client_st *client)
1474
 
{
1475
 
  if (client == NULL)
1476
 
  {
1477
 
    return GEARMAN_INVALID_ARGUMENT;
1478
 
  }
1479
 
 
1480
 
  if (client->task_list == NULL) // We are immediatly successful if all tasks are completed
1481
 
  {
1482
 
    return GEARMAN_SUCCESS;
1483
 
  }
1484
 
 
1485
 
 
1486
 
  _push_non_blocking(client);
1487
 
 
1488
 
  gearman_return_t rc= _client_run_tasks(client);
1489
 
 
1490
 
  _pop_non_blocking(client);
1491
 
 
1492
 
  if (rc == GEARMAN_COULD_NOT_CONNECT)
1493
 
  {
1494
 
    gearman_reset(client->universal);
1495
 
  }
1496
 
 
1497
 
  return rc;
1498
 
}
1499
 
 
1500
 
gearman_return_t gearman_client_run_block_tasks(gearman_client_st *client)
1501
 
{
1502
 
  if (client == NULL)
1503
 
  {
1504
 
    return GEARMAN_INVALID_ARGUMENT;
1505
 
  }
1506
 
 
1507
 
  if (not client->task_list) // We are immediatly successful if all tasks are completed
1508
 
  {
1509
 
    return GEARMAN_SUCCESS;
1510
 
  }
1511
 
 
1512
 
 
1513
 
  _push_blocking(client);
1514
 
 
1515
 
  gearman_return_t rc= _client_run_tasks(client);
1516
 
 
1517
 
  _pop_blocking(client);
1518
 
 
1519
 
  if (gearman_failed(rc))
1520
 
  {
1521
 
    if (rc == GEARMAN_COULD_NOT_CONNECT)
1522
 
    {
1523
 
      gearman_reset(client->universal);
1524
 
    }
1525
 
 
1526
 
    assert(gearman_universal_error_code(client->universal) == rc);
1527
 
  }
1528
 
 
1529
 
  return rc;
1530
 
}
1531
 
 
1532
 
/*
1533
 
 * Static Definitions
1534
 
 */
1535
 
 
1536
 
bool gearman_client_compare(const gearman_client_st *first, const gearman_client_st *second)
1537
 
{
1538
 
  if (first == NULL or second == NULL)
1539
 
  {
1540
 
    return false;
1541
 
  }
1542
 
 
1543
 
  if (strcmp(first->universal.con_list->host, second->universal.con_list->host))
1544
 
  {
1545
 
    return false;
1546
 
  }
1547
 
 
1548
 
  if (first->universal.con_list->port != second->universal.con_list->port)
1549
 
  {
1550
 
    return false;
1551
 
  }
1552
 
 
1553
 
  return true;
1554
 
}
1555
 
 
1556
 
bool gearman_client_set_server_option(gearman_client_st *self, const char *option_arg, size_t option_arg_size)
1557
 
{
1558
 
  if (self == NULL)
1559
 
  {
1560
 
    return false;
1561
 
  }
1562
 
 
1563
 
  gearman_string_t option= { option_arg, option_arg_size };
1564
 
 
1565
 
  return gearman_request_option(self->universal, option);
1566
 
}
1567
 
 
1568
 
void gearman_client_set_namespace(gearman_client_st *self, const char *namespace_key, size_t namespace_key_size)
1569
 
{
1570
 
  if (self == NULL)
1571
 
  {
1572
 
    return;
1573
 
  }
1574
 
 
1575
 
  gearman_universal_set_namespace(self->universal, namespace_key, namespace_key_size);
1576
 
}
1577
 
 
1578
 
gearman_return_t gearman_client_set_identifier(gearman_client_st *client,
1579
 
                                               const char *id, size_t id_size)
1580
 
{
1581
 
  return gearman_set_identifier(client->universal, id, id_size);
1582
 
}
1583