00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef _ASTERISK_SCHED_H
00024 #define _ASTERISK_SCHED_H
00025
00026 #if defined(__cplusplus) || defined(c_plusplus)
00027 extern "C" {
00028 #endif
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define SCHED_MAX_CACHE 128
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #define AST_SCHED_DEL(sched, id) \
00052 do { \
00053 int _count = 0; \
00054 while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
00055 usleep(1); \
00056 } \
00057 if (_count == 10) \
00058 ast_debug(3, "Unable to cancel schedule ID %d.\n", id); \
00059 id = -1; \
00060 } while (0);
00061
00062
00063
00064
00065
00066
00067 #define AST_SCHED_DEL_UNREF(sched, id, refcall) \
00068 do { \
00069 int _count = 0; \
00070 while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
00071 usleep(1); \
00072 } \
00073 if (_count == 10) \
00074 ast_log(LOG_WARNING, "Unable to cancel schedule ID %d. This is probably a bug (%s: %s, line %d).\n", id, __FILE__, __PRETTY_FUNCTION__, __LINE__); \
00075 if (id > -1) \
00076 refcall; \
00077 id = -1; \
00078 } while (0);
00079
00080
00081
00082
00083
00084 #define AST_SCHED_DEL_SPINLOCK(sched, id, lock) \
00085 ({ \
00086 int _count = 0; \
00087 int _sched_res = -1; \
00088 while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) { \
00089 ast_mutex_unlock(lock); \
00090 usleep(1); \
00091 ast_mutex_lock(lock); \
00092 } \
00093 if (_count == 10 && option_debug > 2) { \
00094 ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \
00095 } \
00096 id = -1; \
00097 (_sched_res); \
00098 })
00099
00100 #define AST_SCHED_REPLACE_VARIABLE(id, sched, when, callback, data, variable) \
00101 do { \
00102 int _count = 0; \
00103 while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
00104 usleep(1); \
00105 } \
00106 if (_count == 10) \
00107 ast_log(LOG_WARNING, "Unable to cancel schedule ID %d. This is probably a bug (%s: %s, line %d).\n", id, __FILE__, __PRETTY_FUNCTION__, __LINE__); \
00108 id = ast_sched_add_variable(sched, when, callback, data, variable); \
00109 } while (0);
00110
00111 #define AST_SCHED_REPLACE(id, sched, when, callback, data) \
00112 AST_SCHED_REPLACE_VARIABLE(id, sched, when, callback, data, 0)
00113
00114
00115
00116
00117
00118 #define AST_SCHED_REPLACE_VARIABLE_UNREF(id, sched, when, callback, data, variable, unrefcall, addfailcall, refcall) \
00119 do { \
00120 int _count = 0, _res=1; \
00121 void *_data = (void *)ast_sched_find_data(sched, id); \
00122 while (id > -1 && (_res = ast_sched_del(sched, id) && _count++ < 10)) { \
00123 usleep(1); \
00124 } \
00125 if (!_res && _data) \
00126 unrefcall; \
00127 if (_count == 10) \
00128 ast_log(LOG_WARNING, "Unable to cancel schedule ID %d. This is probably a bug (%s: %s, line %d).\n", id, __FILE__, __PRETTY_FUNCTION__, __LINE__); \
00129 refcall; \
00130 id = ast_sched_add_variable(sched, when, callback, data, variable); \
00131 if (id == -1) \
00132 addfailcall; \
00133 } while (0);
00134
00135 #define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall) \
00136 AST_SCHED_REPLACE_VARIABLE_UNREF(id, sched, when, callback, data, 0, unrefcall, addfailcall, refcall)
00137
00138 struct sched_context;
00139
00140
00141
00142
00143
00144 struct sched_context *sched_context_create(void);
00145
00146
00147
00148
00149
00150
00151 void sched_context_destroy(struct sched_context *c);
00152
00153
00154
00155
00156
00157
00158 typedef int (*ast_sched_cb)(const void *data);
00159 #define AST_SCHED_CB(a) ((ast_sched_cb)(a))
00160
00161 struct ast_cb_names {
00162 int numassocs;
00163 char *list[10];
00164 ast_sched_cb cblist[10];
00165 };
00166
00167
00168
00169
00170
00171
00172
00173
00174 void ast_sched_report(struct sched_context *con, struct ast_str **buf, struct ast_cb_names *cbnames);
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result;
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result;
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result;
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 const void *ast_sched_find_data(struct sched_context *con, int id);
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 #ifndef AST_DEVMODE
00251 int ast_sched_del(struct sched_context *con, int id) attribute_warn_unused_result;
00252 #else
00253 int _ast_sched_del(struct sched_context *con, int id, const char *file, int line, const char *function) attribute_warn_unused_result;
00254 #define ast_sched_del(a, b) _ast_sched_del(a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00255 #endif
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result;
00267
00268
00269
00270
00271
00272
00273
00274
00275 int ast_sched_runq(struct sched_context *con);
00276
00277
00278
00279
00280
00281 void ast_sched_dump(struct sched_context *con);
00282
00283
00284
00285
00286
00287 long ast_sched_when(struct sched_context *con,int id);
00288
00289
00290
00291
00292
00293 #define ast_sched_add_object(obj,con,when,callback) ast_sched_add((con),(when),(callback), ASTOBJ_REF((obj)))
00294
00295
00296
00297
00298
00299 #define ast_sched_del_object(obj,destructor,con,id) do { \
00300 if ((id) > -1) { \
00301 ast_sched_del((con),(id)); \
00302 (id) = -1; \
00303 ASTOBJ_UNREF((obj),(destructor)); \
00304 } \
00305 } while(0)
00306
00307 #if defined(__cplusplus) || defined(c_plusplus)
00308 }
00309 #endif
00310
00311 #endif