Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
ipcLockModule.cpp File Reference
#include <stdlib.h>
#include <stdio.h>
#include "ipcModuleUtil.h"
#include "ipcLockProtocol.h"
#include "plhash.h"
#include "plstr.h"

Go to the source code of this file.

Classes

struct  ipcLockContext

Defines

#define LOG(args)

Functions

static void ipcLockModule_Send (PRUint32 cid, const char *key, PRUint8 opcode)
 ipcLockModule_AllocTable (void *pool, PRSize size)
 ipcLockModule_FreeTable (void *pool, void *item)
 ipcLockModule_AllocEntry (void *pool, const void *key)
 ipcLockModule_FreeEntry (void *pool, PLHashEntry *he, PRUintn flag)
static void ipcLockModule_AcquireLock (PRUint32 cid, PRUint8 flags, const char *key)
static PRBool ipcLockModule_ReleaseLockHelper (PRUint32 cid, const char *key, ipcLockContext *ctx)
static void ipcLockModule_ReleaseLock (PRUint32 cid, const char *key)
 ipcLockModule_ReleaseByCID (PLHashEntry *he, PRIntn i, void *arg)
static void ipcLockModule_Init ()
static void ipcLockModule_Shutdown ()
static void ipcLockModule_HandleMsg (ipcClientHandle client, const nsID &target, const void *data, PRUint32 dataLen)
static void ipcLockModule_ClientUp (ipcClientHandle client)
static void ipcLockModule_ClientDown (ipcClientHandle client)

Variables

static const nsID kLockTargetID = IPC_LOCK_TARGETID
static PLHashTablegLockTable = NULL
static const PLHashAllocOps ipcLockModule_AllocOps
static ipcModuleMethods gLockMethods
static ipcModuleEntry gLockModuleEntry []

Define Documentation

#define LOG (   args)

Definition at line 48 of file ipcLockModule.cpp.


Function Documentation

static void ipcLockModule_AcquireLock ( PRUint32  cid,
PRUint8  flags,
const char *  key 
) [static]

Definition at line 122 of file ipcLockModule.cpp.

{
    LOG(("$$$ acquiring lock [key=%s]\n", key));

    if (!gLockTable)
        return;

    ipcLockContext *ctx;
    
    ctx = (ipcLockContext *) PL_HashTableLookup(gLockTable, key);
    if (ctx) {
        //
        // lock is already acquired, add this client to the queue.  make
        // sure this client doesn't already own the lock or live on the queue.
        //
        while (ctx->mOwnerID != cid && ctx->mNextPending)
            ctx = ctx->mNextPending;
        if (ctx->mOwnerID != cid) {
            //
            // if nonblocking, then send busy status message.  otherwise,
            // proceed to add this client to the pending queue.
            //
            if (flags & IPC_LOCK_FL_NONBLOCKING)
                ipcLockModule_Send(cid, key, IPC_LOCK_OP_STATUS_BUSY);
            else
                ctx->mNextPending = new ipcLockContext(cid);
        }
    }
    else {
        //
        // ok, add this lock to the table, and notify client that it now owns
        // the lock!
        //
        ctx = new ipcLockContext(cid);
        if (!ctx)
            return;

        PL_HashTableAdd(gLockTable, PL_strdup(key), ctx);

        ipcLockModule_Send(cid, key, IPC_LOCK_OP_STATUS_ACQUIRED);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

ipcLockModule_AllocEntry ( void pool,
const void key 
)

Definition at line 100 of file ipcLockModule.cpp.

{
    return (PLHashEntry *) malloc(sizeof(PLHashEntry));
}
ipcLockModule_AllocTable ( void pool,
PRSize  size 
)

Definition at line 88 of file ipcLockModule.cpp.

{
    return malloc(size);
}
static void ipcLockModule_ClientDown ( ipcClientHandle  client) [static]

Definition at line 307 of file ipcLockModule.cpp.

{
    PRUint32 cid = IPC_GetClientID(client);

    LOG(("$$$ ipcLockModule_ClientDown [%u]\n", cid));

    //
    // enumerate lock table, release any locks held by this client.
    //

    PL_HashTableEnumerateEntries(gLockTable, ipcLockModule_ReleaseByCID, &cid);
}

Here is the call graph for this function:

static void ipcLockModule_ClientUp ( ipcClientHandle  client) [static]

Definition at line 301 of file ipcLockModule.cpp.

{
    LOG(("$$$ ipcLockModule_ClientUp [%u]\n", IPC_GetClientID(client)));
}

Here is the call graph for this function:

ipcLockModule_FreeEntry ( void pool,
PLHashEntry he,
PRUintn  flag 
)

Definition at line 106 of file ipcLockModule.cpp.

{
    PL_strfree((char *) he->key);
    free(he);
}
ipcLockModule_FreeTable ( void pool,
void item 
)

Definition at line 94 of file ipcLockModule.cpp.

{
    free(item);
}
static void ipcLockModule_HandleMsg ( ipcClientHandle  client,
const nsID target,
const void data,
PRUint32  dataLen 
) [static]

Definition at line 276 of file ipcLockModule.cpp.

{
    PRUint32 cid = IPC_GetClientID(client);

    LOG(("$$$ ipcLockModule_HandleMsg [cid=%u]\n", cid));

    ipcLockMsg msg;
    IPC_UnflattenLockMsg((const PRUint8 *) data, dataLen, &msg);

    switch (msg.opcode) {
    case IPC_LOCK_OP_ACQUIRE:
        ipcLockModule_AcquireLock(cid, msg.flags, msg.key);
        break;
    case IPC_LOCK_OP_RELEASE:
        ipcLockModule_ReleaseLock(cid, msg.key);
        break;
    default:
        PR_NOT_REACHED("invalid opcode");
    }
}

Here is the call graph for this function:

static void ipcLockModule_Init ( ) [static]

Definition at line 250 of file ipcLockModule.cpp.

Here is the call graph for this function:

ipcLockModule_ReleaseByCID ( PLHashEntry he,
PRIntn  i,
void arg 
)

Definition at line 230 of file ipcLockModule.cpp.

{
    PRUint32 cid = *(PRUint32 *) arg;

    ipcLockContext *ctx = (ipcLockContext *) he->value;
    if (ctx->mOwnerID != cid)
        return HT_ENUMERATE_NEXT;

    LOG(("$$$ ipcLockModule_ReleaseByCID [cid=%u key=%s he=%p]\n",
        cid, (char*)he->key, (void*)he));

    if (ipcLockModule_ReleaseLockHelper(cid, (const char *) he->key, ctx))
        return HT_ENUMERATE_REMOVE;

    return HT_ENUMERATE_NEXT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ipcLockModule_ReleaseLock ( PRUint32  cid,
const char *  key 
) [static]

Definition at line 217 of file ipcLockModule.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool ipcLockModule_ReleaseLockHelper ( PRUint32  cid,
const char *  key,
ipcLockContext ctx 
) [static]

Definition at line 166 of file ipcLockModule.cpp.

{
    LOG(("$$$ releasing lock [key=%s]\n", key));

    PRBool removeEntry = PR_FALSE;

    //
    // lock is already acquired _or_ maybe client is on the pending list.
    //
    if (ctx->mOwnerID == cid) {
        if (ctx->mNextPending) {
            //
            // remove this element from the list.  since this is the
            // first element in the list, instead of removing it we
            // shift the data from the next context into this one and
            // delete the next context.
            //
            ipcLockContext *next = ctx->mNextPending;
            ctx->mOwnerID = next->mOwnerID;
            ctx->mNextPending = next->mNextPending;
            delete next;
            //
            // notify client that it now owns the lock
            //
            ipcLockModule_Send(ctx->mOwnerID, key, IPC_LOCK_OP_STATUS_ACQUIRED);
        }
        else {
            delete ctx;
            removeEntry = PR_TRUE;
        }
    }
    else {
        ipcLockContext *prev;
        for (;;) {
            prev = ctx;
            ctx = ctx->mNextPending;
            if (!ctx)
                break;
            if (ctx->mOwnerID == cid) {
                // remove ctx from list
                prev->mNextPending = ctx->mNextPending;
                delete ctx;
                break;
            }
        }
    }

    return removeEntry;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ipcLockModule_Send ( PRUint32  cid,
const char *  key,
PRUint8  opcode 
) [static]

Definition at line 54 of file ipcLockModule.cpp.

{
    ipcLockMsg msg = { opcode, 0, key };
    PRUint32 bufLen;
    PRUint8 *buf = IPC_FlattenLockMsg(&msg, &bufLen);
    if (!buf)
        return;
    IPC_SendMsg(cid, kLockTargetID, buf, bufLen);
    free(buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ipcLockModule_Shutdown ( ) [static]

Definition at line 263 of file ipcLockModule.cpp.

{
    LOG(("$$$ ipcLockModule_Shutdown\n"));
    
    if (gLockTable) {
        // XXX walk table destroying all ipcLockContext objects
 
        PL_HashTableDestroy(gLockTable);
        gLockTable = NULL;
    }
}

Here is the call graph for this function:


Variable Documentation

Initial value:

Definition at line 332 of file ipcLockModule.cpp.

Definition at line 70 of file ipcLockModule.cpp.

Definition at line 51 of file ipcLockModule.cpp.