Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

module.h File Reference

Go to the source code of this file.

Defines

#define ASTERISK_GPL_KEY   "This paragraph is Copyright (C) 2000, Linux Support Services, Inc. \In order for your module to load, it must return this key via a function \called \"key\". Any code which includes this paragraph must be licensed under \the GNU General Public License version 2 or later (at your option). Linux \Support Services, Inc. reserves the right to allow other parties to license \this paragraph under other terms as well."
#define AST_MODULE_CONFIG   "modules.conf" /*! Module configuration file */
#define AST_FORCE_SOFT   0
#define AST_FORCE_FIRM   1
#define AST_FORCE_HARD   2
#define STANDARD_LOCAL_USER
#define LOCAL_USER_DECL
#define LOCAL_USER_ADD(u)
#define LOCAL_USER_REMOVE(u)
#define STANDARD_HANGUP_LOCALUSERS
#define STANDARD_USECOUNT(res)

Functions

int load_module (void)
 Initialize the module.

int unload_module (void)
 Cleanup all module structures, sockets, etc.

int usecount (void)
 Provides a usecount.

char * description (void)
 Description.

char * key (void)
 Returns the ASTERISK_GPL_KEY.

int reload (void)
 Reload stuff.

int ast_load_resource (char *resource_name)
 Loads a module.

int ast_unload_resource (char *resource_name, int force)
 Unloads a module.

void ast_update_use_count (void)
 Notify when usecount has been changed.

int ast_update_module_list (int(*modentry)(char *module, char *description, int usecnt))
 Ask for a list of modules, descriptions, and use counts.

int ast_loader_register (int(*updater)(void))
 Ask this procedure to be run with modules have been updated.

int ast_loader_unregister (int(*updater)(void))
 No longer run me when modules are updated.

void ast_module_reload (void)
 Reload all modules.

int ast_register_atexit (void(*func)(void))
void ast_unregister_atexit (void(*func)(void))


Define Documentation

#define AST_FORCE_FIRM   1
 

Definition at line 81 of file module.h.

Referenced by ast_unload_resource().

#define AST_FORCE_HARD   2
 

Definition at line 82 of file module.h.

#define AST_FORCE_SOFT   0
 

Definition at line 80 of file module.h.

#define AST_MODULE_CONFIG   "modules.conf" /*! Module configuration file */
 

Definition at line 77 of file module.h.

Referenced by ast_load_resource(), and load_modules().

#define ASTERISK_GPL_KEY   "This paragraph is Copyright (C) 2000, Linux Support Services, Inc. \In order for your module to load, it must return this key via a function \called \"key\". Any code which includes this paragraph must be licensed under \the GNU General Public License version 2 or later (at your option). Linux \Support Services, Inc. reserves the right to allow other parties to license \this paragraph under other terms as well."
 

reload configs

Definition at line 69 of file module.h.

#define LOCAL_USER_ADD  ) 
 

Definition at line 160 of file module.h.

#define LOCAL_USER_DECL
 

Value:

static ast_mutex_t localuser_lock = AST_MUTEX_INITIALIZER; \
                  static struct localuser *localusers = NULL; \
                  static int localusecnt = 0;

Definition at line 156 of file module.h.

#define LOCAL_USER_REMOVE  ) 
 

Definition at line 175 of file module.h.

#define STANDARD_HANGUP_LOCALUSERS
 

Definition at line 196 of file module.h.

#define STANDARD_LOCAL_USER
 

Value:

struct localuser { \
                        struct ast_channel *chan; \
                        struct localuser *next; \
                     }

Definition at line 151 of file module.h.

#define STANDARD_USECOUNT res   ) 
 

Value:

{ \
   ast_mutex_lock(&localuser_lock); \
   res = localusecnt; \
   ast_mutex_unlock(&localuser_lock); \
}

Definition at line 210 of file module.h.


Function Documentation

int ast_load_resource char *  resource_name  ) 
 

Loads a module.

Parameters:
resource_name the filename of the module to load This function is ran by the PBX to load the modules. It performs all loading, setting up of it's module related data structures, etc. Basically, to load a module, you just give it the name of the module and it will do the rest. It returns 0 on success, -1 on error

Definition at line 178 of file loader.c.

References ast_config_AST_MODULE_DIR, ast_destroy(), ast_load(), ast_log(), AST_MODULE_CONFIG, ast_mutex_lock, ast_mutex_unlock, ast_true(), ast_unload_resource(), ast_update_use_count(), ast_variable_retrieve(), ast_verbose(), COLOR_BLACK, COLOR_BROWN, dlclose(), dlerror(), dlopen(), dlsym(), free, fully_booted, LOG_WARNING, malloc, option_console, option_verbose, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, term_color(), and VERBOSE_PREFIX_1.

Referenced by load_modules().

00179 {
00180    static char fn[256];
00181    int errors=0;
00182    int res;
00183    struct module *m;
00184    int flags=RTLD_NOW;
00185 #ifdef RTLD_GLOBAL
00186    char *val;
00187 #endif
00188    char *key;
00189    int o;
00190    struct ast_config *cfg;
00191    char tmp[80];
00192    /* Keep the module file parsing silent */
00193    o = option_verbose;
00194    if (strncasecmp(resource_name, "res_", 4)) {
00195       option_verbose = 0;
00196       cfg = ast_load(AST_MODULE_CONFIG);
00197       option_verbose = o;
00198       if (cfg) {
00199 #ifdef RTLD_GLOBAL
00200          if ((val = ast_variable_retrieve(cfg, "global", resource_name))
00201                && ast_true(val))
00202             flags |= RTLD_GLOBAL;
00203 #endif
00204          ast_destroy(cfg);
00205       }
00206    } else {
00207       /* Resource modules are always loaded global and lazy */
00208 #ifdef RTLD_GLOBAL
00209       flags = (RTLD_GLOBAL | RTLD_LAZY);
00210 #else
00211       flags = RTLD_LAZY;
00212 #endif
00213    }
00214    
00215    if (ast_mutex_lock(&modlock))
00216       ast_log(LOG_WARNING, "Failed to lock\n");
00217    m = module_list;
00218    while(m) {
00219       if (!strcasecmp(m->resource, resource_name)) {
00220          ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name);
00221          ast_mutex_unlock(&modlock);
00222          return -1;
00223       }
00224       m = m->next;
00225    }
00226    m = malloc(sizeof(struct module));  
00227    if (!m) {
00228       ast_log(LOG_WARNING, "Out of memory\n");
00229       ast_mutex_unlock(&modlock);
00230       return -1;
00231    }
00232    strncpy(m->resource, resource_name, sizeof(m->resource)-1);
00233    if (resource_name[0] == '/') {
00234       strncpy(fn, resource_name, sizeof(fn)-1);
00235    } else {
00236       snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name);
00237    }
00238    m->lib = dlopen(fn, flags);
00239    if (!m->lib) {
00240       ast_log(LOG_WARNING, "%s\n", dlerror());
00241       free(m);
00242       ast_mutex_unlock(&modlock);
00243       return -1;
00244    }
00245    m->load_module = dlsym(m->lib, "load_module");
00246    if (m->load_module == NULL)
00247       m->load_module = dlsym(m->lib, "_load_module");
00248    if (!m->load_module) {
00249       ast_log(LOG_WARNING, "No load_module in module %s\n", fn);
00250       errors++;
00251    }
00252    m->unload_module = dlsym(m->lib, "unload_module");
00253    if (m->unload_module == NULL)
00254       m->unload_module = dlsym(m->lib, "_unload_module");
00255    if (!m->unload_module) {
00256       ast_log(LOG_WARNING, "No unload_module in module %s\n", fn);
00257       errors++;
00258    }
00259    m->usecount = dlsym(m->lib, "usecount");
00260    if (m->usecount == NULL)
00261       m->usecount = dlsym(m->lib, "_usecount");
00262    if (!m->usecount) {
00263       ast_log(LOG_WARNING, "No usecount in module %s\n", fn);
00264       errors++;
00265    }
00266    m->description = dlsym(m->lib, "description");
00267    if (m->description == NULL)
00268       m->description = dlsym(m->lib, "_description");
00269    if (!m->description) {
00270       ast_log(LOG_WARNING, "No description in module %s\n", fn);
00271       errors++;
00272    }
00273    m->key = dlsym(m->lib, "key");
00274    if (m->key == NULL)
00275       m->key = dlsym(m->lib, "_key");
00276    if (!m->key) {
00277       ast_log(LOG_WARNING, "No key routine in module %s\n", fn);
00278       errors++;
00279    }
00280    m->reload = dlsym(m->lib, "reload");
00281    if (m->reload == NULL)
00282       m->reload = dlsym(m->lib, "_reload");
00283    if (m->key && !(key = m->key())) {
00284       ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn);
00285       errors++;
00286    } else
00287       key = NULL;
00288    if (key && verify_key(key)) {
00289       ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn);
00290       errors++;
00291    }
00292    if (errors) {
00293       ast_log(LOG_WARNING, "%d error(s) loading module %s, aborted\n", errors, fn);
00294       dlclose(m->lib);
00295       free(m);
00296       ast_mutex_unlock(&modlock);
00297       return -1;
00298    }
00299    if (!fully_booted) {
00300       if (option_verbose) 
00301          ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
00302       if (option_console && !option_verbose)
00303          ast_verbose( ".");
00304    } else {
00305       if (option_verbose)
00306          ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description());
00307    }
00308    m->next = module_list;
00309    
00310    module_list = m;
00311    ast_mutex_unlock(&modlock);
00312    if ((res = m->load_module())) {
00313       ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res);
00314       ast_unload_resource(resource_name, 0);
00315       return -1;
00316    }
00317    ast_update_use_count();
00318    return 0;
00319 }  

int ast_loader_register int(*  updater)(void)  ) 
 

Ask this procedure to be run with modules have been updated.

Parameters:
updater the function to run when modules have been updated This function adds the given function to a linked list of functions to be run when the modules are updated. It returns 0 on success and -1 on failure.

Definition at line 458 of file loader.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_WARNING, and malloc.

00459 {
00460    struct loadupdate *tmp;
00461    /* XXX Should be more flexible here, taking > 1 verboser XXX */
00462    if ((tmp = malloc(sizeof (struct loadupdate)))) {
00463       tmp->updater = v;
00464       if (ast_mutex_lock(&modlock))
00465          ast_log(LOG_WARNING, "Failed to lock\n");
00466       tmp->next = updaters;
00467       updaters = tmp;
00468       ast_mutex_unlock(&modlock);
00469       return 0;
00470    }
00471    return -1;
00472 }

int ast_loader_unregister int(*  updater)(void)  ) 
 

No longer run me when modules are updated.

Parameters:
updater function to unregister This removes the given function from the updater list. It returns 0 on success, -1 on failure.

Definition at line 474 of file loader.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING.

00475 {
00476    int res = -1;
00477    struct loadupdate *tmp, *tmpl=NULL;
00478    if (ast_mutex_lock(&modlock))
00479       ast_log(LOG_WARNING, "Failed to lock\n");
00480    tmp = updaters;
00481    while(tmp) {
00482       if (tmp->updater == v)  {
00483          if (tmpl)
00484             tmpl->next = tmp->next;
00485          else
00486             updaters = tmp->next;
00487          break;
00488       }
00489       tmpl = tmp;
00490       tmp = tmp->next;
00491    }
00492    if (tmp)
00493       res = 0;
00494    ast_mutex_unlock(&modlock);
00495    return res;
00496 }

void ast_module_reload void   ) 
 

Reload all modules.

This reloads all modules set to load in asterisk. It does NOT run the unload routine and then loads them again, it runs the given reload routine.

Definition at line 149 of file loader.c.

References ast_enum_reload(), ast_lastreloadtime, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_rtp_reload(), ast_verbose(), option_verbose, reload_manager(), and VERBOSE_PREFIX_3.

00150 {
00151    struct module *m;
00152 
00153    /* We'll do the logger and manager the favor of calling its reload here first */
00154 
00155    if (ast_mutex_trylock(&reloadlock)) {
00156       ast_verbose("The previous reload command didn't finish yet\n");
00157       return;
00158    }
00159    reload_manager();
00160    ast_enum_reload();
00161    ast_rtp_reload();
00162    time(&ast_lastreloadtime);
00163 
00164    ast_mutex_lock(&modlock);
00165    m = module_list;
00166    while(m) {
00167       if (m->reload) {
00168          if (option_verbose > 2) 
00169             ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description());
00170          m->reload();
00171       }
00172       m = m->next;
00173    }
00174    ast_mutex_unlock(&modlock);
00175    ast_mutex_unlock(&reloadlock);
00176 }

int ast_register_atexit void(*  func)(void)  ) 
 

Definition at line 115 of file asterisk.c.

References ast_mutex_lock, ast_mutex_unlock, ast_unregister_atexit(), and malloc.

00116 {
00117    int res = -1;
00118    struct ast_atexit *ae;
00119    ast_unregister_atexit(func);
00120    ae = malloc(sizeof(struct ast_atexit));
00121    ast_mutex_lock(&atexitslock);
00122    if (ae) {
00123       memset(ae, 0, sizeof(struct ast_atexit));
00124       ae->next = atexits;
00125       ae->func = func;
00126       atexits = ae;
00127       res = 0;
00128    }
00129    ast_mutex_unlock(&atexitslock);
00130    return res;
00131 }

int ast_unload_resource char *  resource_name,
int  force
 

Unloads a module.

Parameters:
resourcename the name of the module to unload
force the force flag. Setting this to non-zero will force the module to be unloaded This function unloads a particular module. If the force flag is not set, it will not unload a module with a usecount > 0. However, if it is set, it will unload the module regardless of consequences (NOT_RECOMMENDED)

Definition at line 106 of file loader.c.

References AST_FORCE_FIRM, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_update_use_count(), dlclose(), free, LOG_WARNING, and module::next.

Referenced by ast_load_resource().

00107 {
00108    struct module *m, *ml = NULL;
00109    int res = -1;
00110    if (ast_mutex_lock(&modlock))
00111       ast_log(LOG_WARNING, "Failed to lock\n");
00112    m = module_list;
00113    while(m) {
00114       if (!strcasecmp(m->resource, resource_name)) {
00115          if ((res = m->usecount()) > 0)  {
00116             if (force) 
00117                ast_log(LOG_WARNING, "Warning:  Forcing removal of module %s with use count %d\n", resource_name, res);
00118             else {
00119                ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res);
00120                ast_mutex_unlock(&modlock);
00121                return -1;
00122             }
00123          }
00124          res = m->unload_module();
00125          if (res) {
00126             ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
00127             if (force <= AST_FORCE_FIRM) {
00128                ast_mutex_unlock(&modlock);
00129                return -1;
00130             } else
00131                ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
00132          }
00133          if (ml)
00134             ml->next = m->next;
00135          else
00136             module_list = m->next;
00137          dlclose(m->lib);
00138          free(m);
00139          break;
00140       }
00141       ml = m;
00142       m = m->next;
00143    }
00144    ast_mutex_unlock(&modlock);
00145    ast_update_use_count();
00146    return res;
00147 }

void ast_unregister_atexit void(*  func)(void)  ) 
 

Definition at line 133 of file asterisk.c.

References ast_mutex_lock, and ast_mutex_unlock.

Referenced by ast_register_atexit().

00134 {
00135    struct ast_atexit *ae, *prev = NULL;
00136    ast_mutex_lock(&atexitslock);
00137    ae = atexits;
00138    while(ae) {
00139       if (ae->func == func) {
00140          if (prev)
00141             prev->next = ae->next;
00142          else
00143             atexits = ae->next;
00144          break;
00145       }
00146       prev = ae;
00147       ae = ae->next;
00148    }
00149    ast_mutex_unlock(&atexitslock);
00150 }

int ast_update_module_list int(*  modentry)(char *module, char *description, int usecnt)  ) 
 

Ask for a list of modules, descriptions, and use counts.

Parameters:
modentry a callback to an updater function For each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module.

Definition at line 442 of file loader.c.

References ast_mutex_trylock, ast_mutex_unlock, and module::next.

00443 {
00444    struct module *m;
00445    int unlock = -1;
00446    if (ast_mutex_trylock(&modlock))
00447       unlock = 0;
00448    m = module_list;
00449    while(m) {
00450       modentry(m->resource, m->description(), m->usecount());
00451       m = m->next;
00452    }
00453    if (unlock)
00454       ast_mutex_unlock(&modlock);
00455    return 0;
00456 }

void ast_update_use_count void   ) 
 

Notify when usecount has been changed.

This function goes through and calulates use counts. It also notifies anybody trying to keep track of them.

Definition at line 426 of file loader.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING.

Referenced by ast_load_resource(), and ast_unload_resource().

00427 {
00428    /* Notify any module monitors that the use count for a 
00429       resource has changed */
00430    struct loadupdate *m;
00431    if (ast_mutex_lock(&modlock))
00432       ast_log(LOG_WARNING, "Failed to lock\n");
00433    m = updaters;
00434    while(m) {
00435       m->updater();
00436       m = m->next;
00437    }
00438    ast_mutex_unlock(&modlock);
00439    
00440 }

char* description void   ) 
 

Description.

Returns a short description of your module.

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message, i.e. char *key(void){return ASTERISK_GPL_KEY;}

int load_module void   ) 
 

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

int reload void   ) 
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload. Return 0 on success, and other than 0 on problem.

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit). Return 0 on success, or other than 0 if there is a problem.

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere.


Generated on Sun Apr 18 23:34:08 2004 for Asterisk by doxygen 1.3.6-20040222