Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
ipcModuleReg.cpp File Reference
#include <string.h>
#include <stdlib.h>
#include "prlink.h"
#include "prio.h"
#include "prlog.h"
#include "plstr.h"
#include "ipcConfig.h"
#include "ipcLog.h"
#include "ipcModuleReg.h"
#include "ipcModule.h"
#include "ipcCommandModule.h"
#include "ipcd.h"

Go to the source code of this file.

Classes

struct  ipcModuleRegEntry

Defines

#define IPC_MAX_MODULE_COUNT   64

Functions

static PRStatus AddModule (const nsID &target, ipcModuleMethods *methods, const char *libPath)
static void InitModuleFromLib (const char *modulesDir, const char *fileName)
void IPC_InitModuleReg (const char *exePath)
void IPC_ShutdownModuleReg ()
void IPC_NotifyModulesClientUp (ipcClient *client)
void IPC_NotifyModulesClientDown (ipcClient *client)
PRStatus IPC_DispatchMsg (ipcClient *client, const nsID &target, const void *data, PRUint32 dataLen)

Variables

static ipcModuleRegEntry ipcModules [IPC_MAX_MODULE_COUNT]
static int ipcModuleCount = 0

Class Documentation

struct ipcModuleRegEntry

Definition at line 55 of file ipcModuleReg.cpp.

Collaboration diagram for ipcModuleRegEntry:
Class Members
PRLibrary * lib
ipcModuleMethods * methods
nsID target

Define Documentation

Definition at line 62 of file ipcModuleReg.cpp.


Function Documentation

static PRStatus AddModule ( const nsID target,
ipcModuleMethods methods,
const char *  libPath 
) [static]

Definition at line 70 of file ipcModuleReg.cpp.

{
    if (ipcModuleCount == IPC_MAX_MODULE_COUNT) {
        LOG(("too many modules!\n"));
        return PR_FAILURE;
    }

    if (!methods) {
        PR_NOT_REACHED("null module methods");
        return PR_FAILURE;
    }

    //
    // each ipcModuleRegEntry holds a reference to a PRLibrary, and on
    // shutdown, each PRLibrary reference will be released.  this ensures
    // that the library will not be unloaded until all of the modules in
    // that library are shutdown.
    //
    ipcModules[ipcModuleCount].target = target;
    ipcModules[ipcModuleCount].methods = methods;
    ipcModules[ipcModuleCount].lib = PR_LoadLibrary(libPath);

    ++ipcModuleCount;
    return PR_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void InitModuleFromLib ( const char *  modulesDir,
const char *  fileName 
) [static]

Definition at line 97 of file ipcModuleReg.cpp.

{
    LOG(("InitModuleFromLib [%s]\n", fileName));

    static const ipcDaemonMethods gDaemonMethods =
    {
        IPC_DAEMON_METHODS_VERSION,
        IPC_DispatchMsg,
        IPC_SendMsg,
        IPC_GetClientByID,
        IPC_GetClientByName,
        IPC_EnumClients,
        IPC_GetClientID,
        IPC_ClientHasName,
        IPC_ClientHasTarget,
        IPC_EnumClientNames,
        IPC_EnumClientTargets
    };

    int dLen = strlen(modulesDir);
    int fLen = strlen(fileName);

    char *buf = (char *) malloc(dLen + 1 + fLen + 1);
    memcpy(buf, modulesDir, dLen);
    buf[dLen] = IPC_PATH_SEP_CHAR;
    memcpy(buf + dLen + 1, fileName, fLen);
    buf[dLen + 1 + fLen] = '\0';

    PRLibrary *lib = PR_LoadLibrary(buf);
    if (lib) {
        ipcGetModulesFunc func =
            (ipcGetModulesFunc) PR_FindFunctionSymbol(lib, "IPC_GetModules");

        LOG(("  func=%p\n", (void*) func));

        if (func) {
            const ipcModuleEntry *entries = NULL;
            int count = func(&gDaemonMethods, &entries);
            for (int i=0; i<count; ++i) {
                if (AddModule(entries[i].target, entries[i].methods, buf) == PR_SUCCESS) {
                    if (entries[i].methods->init)
                        entries[i].methods->init();
                }
            }
        }
        PR_UnloadLibrary(lib);
    }

    free(buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRStatus IPC_DispatchMsg ( ipcClient client,
const nsID target,
const void data,
PRUint32  dataLen 
)

Definition at line 234 of file ipcModuleReg.cpp.

{
    // dispatch message to every module registered under the given target.
    for (int i=0; i<ipcModuleCount; ++i) {
        ipcModuleRegEntry &entry = ipcModules[i];
        if (entry.target.Equals(target)) {
            if (entry.methods->handleMsg)
                entry.methods->handleMsg(client, target, data, dataLen);
        }
    }
    return PR_SUCCESS;
}

Here is the call graph for this function:

void IPC_InitModuleReg ( const char *  exePath)

Definition at line 153 of file ipcModuleReg.cpp.

{
    if (!(exePath && *exePath))
        return;

    //
    // register plug-in modules
    //
    char *p = PL_strrchr(exePath, IPC_PATH_SEP_CHAR);
    if (p == NULL) {
        LOG(("unexpected exe path\n"));
        return;
    }

    int baseLen = p - exePath;
    int finalLen = baseLen + 1 + sizeof(IPC_MODULES_DIR);

    // build full path to ipc modules
    char *modulesDir = (char*) malloc(finalLen);
    memcpy(modulesDir, exePath, baseLen);
    modulesDir[baseLen] = IPC_PATH_SEP_CHAR;
    memcpy(modulesDir + baseLen + 1, IPC_MODULES_DIR, sizeof(IPC_MODULES_DIR));

    LOG(("loading libraries in %s\n", modulesDir));
    // 
    // scan directory for IPC modules
    //
    PRDir *dir = PR_OpenDir(modulesDir);
    if (dir) {
        PRDirEntry *ent;
        while ((ent = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
            // 
            // locate extension, and check if dynamic library
            //

            const char *p = strrchr(ent->name, '.');
            if (p && PL_strcasecmp(p, MOZ_DLL_SUFFIX) == 0)
                InitModuleFromLib(modulesDir, ent->name);
        }
        PR_CloseDir(dir);
    }

    free(modulesDir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 224 of file ipcModuleReg.cpp.

{
    for (int i = 0; i < ipcModuleCount; ++i) {
        ipcModuleRegEntry &entry = ipcModules[i];
        if (entry.methods->clientDown)
            entry.methods->clientDown(client);
    }
}

Here is the caller graph for this function:

Definition at line 214 of file ipcModuleReg.cpp.

{
    for (int i = 0; i < ipcModuleCount; ++i) {
        ipcModuleRegEntry &entry = ipcModules[i];
        if (entry.methods->clientUp)
            entry.methods->clientUp(client);
    }
}

Here is the caller graph for this function:

Definition at line 199 of file ipcModuleReg.cpp.

{
    //
    // shutdown modules in reverse order    
    //
    while (ipcModuleCount) {
        ipcModuleRegEntry &entry = ipcModules[--ipcModuleCount];
        if (entry.methods->shutdown)
            entry.methods->shutdown();
        if (entry.lib)
            PR_UnloadLibrary(entry.lib);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int ipcModuleCount = 0 [static]

Definition at line 65 of file ipcModuleReg.cpp.

Definition at line 64 of file ipcModuleReg.cpp.