root/lib/tevent/tevent_queue.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tevent_queue_entry_destructor
  2. tevent_queue_destructor
  3. _tevent_queue_create
  4. tevent_queue_immediate_trigger
  5. tevent_queue_add
  6. tevent_queue_start
  7. tevent_queue_stop
  8. tevent_queue_length

   1 /*
   2    Unix SMB/CIFS implementation.
   3    Infrastructure for async requests
   4    Copyright (C) Volker Lendecke 2008
   5    Copyright (C) Stefan Metzmacher 2009
   6 
   7      ** NOTE! The following LGPL license applies to the tevent
   8      ** library. This does NOT imply that all of Samba is released
   9      ** under the LGPL
  10 
  11    This library is free software; you can redistribute it and/or
  12    modify it under the terms of the GNU Lesser General Public
  13    License as published by the Free Software Foundation; either
  14    version 3 of the License, or (at your option) any later version.
  15 
  16    This library is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19    Lesser General Public License for more details.
  20 
  21    You should have received a copy of the GNU Lesser General Public
  22    License along with this library; if not, see <http://www.gnu.org/licenses/>.
  23 */
  24 
  25 #include "replace.h"
  26 #include "tevent.h"
  27 #include "tevent_internal.h"
  28 #include "tevent_util.h"
  29 
  30 struct tevent_queue_entry {
  31         struct tevent_queue_entry *prev, *next;
  32         struct tevent_queue *queue;
  33 
  34         bool triggered;
  35 
  36         struct tevent_req *req;
  37         struct tevent_context *ev;
  38 
  39         tevent_queue_trigger_fn_t trigger;
  40         void *private_data;
  41 };
  42 
  43 struct tevent_queue {
  44         const char *name;
  45         const char *location;
  46 
  47         bool running;
  48         struct tevent_immediate *immediate;
  49 
  50         size_t length;
  51         struct tevent_queue_entry *list;
  52 };
  53 
  54 static void tevent_queue_immediate_trigger(struct tevent_context *ev,
  55                                            struct tevent_immediate *im,
  56                                            void *private_data);
  57 
  58 static int tevent_queue_entry_destructor(struct tevent_queue_entry *e)
     /* [<][>][^][v][top][bottom][index][help] */
  59 {
  60         struct tevent_queue *q = e->queue;
  61 
  62         if (!q) {
  63                 return 0;
  64         }
  65 
  66         DLIST_REMOVE(q->list, e);
  67         q->length--;
  68 
  69         if (!q->running) {
  70                 return 0;
  71         }
  72 
  73         if (!q->list) {
  74                 return 0;
  75         }
  76 
  77         if (q->list->triggered) {
  78                 return 0;
  79         }
  80 
  81         tevent_schedule_immediate(q->immediate,
  82                                   q->list->ev,
  83                                   tevent_queue_immediate_trigger,
  84                                   q);
  85 
  86         return 0;
  87 }
  88 
  89 static int tevent_queue_destructor(struct tevent_queue *q)
     /* [<][>][^][v][top][bottom][index][help] */
  90 {
  91         q->running = false;
  92 
  93         while (q->list) {
  94                 struct tevent_queue_entry *e = q->list;
  95                 talloc_free(e);
  96         }
  97 
  98         return 0;
  99 }
 100 
 101 struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 102                                           const char *name,
 103                                           const char *location)
 104 {
 105         struct tevent_queue *queue;
 106 
 107         queue = talloc_zero(mem_ctx, struct tevent_queue);
 108         if (!queue) {
 109                 return NULL;
 110         }
 111 
 112         queue->name = talloc_strdup(queue, name);
 113         if (!queue->name) {
 114                 talloc_free(queue);
 115                 return NULL;
 116         }
 117         queue->immediate = tevent_create_immediate(queue);
 118         if (!queue->immediate) {
 119                 talloc_free(queue);
 120                 return NULL;
 121         }
 122 
 123         queue->location = location;
 124 
 125         /* queue is running by default */
 126         queue->running = true;
 127 
 128         talloc_set_destructor(queue, tevent_queue_destructor);
 129         return queue;
 130 }
 131 
 132 static void tevent_queue_immediate_trigger(struct tevent_context *ev,
     /* [<][>][^][v][top][bottom][index][help] */
 133                                            struct tevent_immediate *im,
 134                                            void *private_data)
 135 {
 136         struct tevent_queue *q = talloc_get_type(private_data,
 137                                   struct tevent_queue);
 138 
 139         if (!q->running) {
 140                 return;
 141         }
 142 
 143         q->list->triggered = true;
 144         q->list->trigger(q->list->req, q->list->private_data);
 145 }
 146 
 147 bool tevent_queue_add(struct tevent_queue *queue,
     /* [<][>][^][v][top][bottom][index][help] */
 148                       struct tevent_context *ev,
 149                       struct tevent_req *req,
 150                       tevent_queue_trigger_fn_t trigger,
 151                       void *private_data)
 152 {
 153         struct tevent_queue_entry *e;
 154 
 155         e = talloc_zero(req, struct tevent_queue_entry);
 156         if (e == NULL) {
 157                 return false;
 158         }
 159 
 160         e->queue = queue;
 161         e->req = req;
 162         e->ev = ev;
 163         e->trigger = trigger;
 164         e->private_data = private_data;
 165 
 166         DLIST_ADD_END(queue->list, e, struct tevent_queue_entry *);
 167         queue->length++;
 168         talloc_set_destructor(e, tevent_queue_entry_destructor);
 169 
 170         if (!queue->running) {
 171                 return true;
 172         }
 173 
 174         if (queue->list->triggered) {
 175                 return true;
 176         }
 177 
 178         tevent_schedule_immediate(queue->immediate,
 179                                   queue->list->ev,
 180                                   tevent_queue_immediate_trigger,
 181                                   queue);
 182 
 183         return true;
 184 }
 185 
 186 void tevent_queue_start(struct tevent_queue *queue)
     /* [<][>][^][v][top][bottom][index][help] */
 187 {
 188         if (queue->running) {
 189                 /* already started */
 190                 return;
 191         }
 192 
 193         queue->running = true;
 194 
 195         if (!queue->list) {
 196                 return;
 197         }
 198 
 199         if (queue->list->triggered) {
 200                 return;
 201         }
 202 
 203         tevent_schedule_immediate(queue->immediate,
 204                                   queue->list->ev,
 205                                   tevent_queue_immediate_trigger,
 206                                   queue);
 207 }
 208 
 209 void tevent_queue_stop(struct tevent_queue *queue)
     /* [<][>][^][v][top][bottom][index][help] */
 210 {
 211         queue->running = false;
 212 }
 213 
 214 size_t tevent_queue_length(struct tevent_queue *queue)
     /* [<][>][^][v][top][bottom][index][help] */
 215 {
 216         return queue->length;
 217 }

/* [<][>][^][v][top][bottom][index][help] */