Files
m241Neelima/components/ip_net2-6.9/ipmip/include/private/ipmip_context.h
T
2026-07-30 11:19:44 +05:30

979 lines
28 KiB
C

/* ipmip_context.h - ipmip_context.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip_context.h,v $ $Revision: 1.23 $
* $Source: /home/interpeak/CVSRoot/ipmip/include/private/ipmip_context.h,v $
* $Author: jhorteli $ $Date: 2011-01-21 15:31:28 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIP_CONTEXT_H
#define IPMIP_CONTEXT_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
* MIP context definitions. Deals with process creation, and context
* instantiations.
*/
/*
DESCRIPTION
MIP context definitions. Deals with process creation, and context
instantiations.
There are two types of contexts in the MIP setup, one is the Mobility
Context, which exists only one per mobility agent, and the second is
the process context which exists one for each thread/process.
Most functions in the MIP code base requires both the mobility context and
process context to be passed to it as arguments.
The mobility context is inherited by higher layers (so far IPMIP6 and IPMIP4)
which defines additional functionality beyond what is provided by the base
IPMIP implementation. The base IPMIP implementation initializes and handles
features such as timers, DHCP for v4 and v6, packet buffer management, ARP,
command line interface communication and netlink setup as well as logging
and event management.
EXAMPLE
To create, initialize, start stop and destroy a context.
.CS
/@ Just some sort of entity that one could have in a mobility systemm which
requires a unique identifier @/
struct Ipmip_my_entities
{
char name[16]; /@ Name for this entity @/
unsigned short identity; /@ Identity for this entity @/
Ipmip_timer_lock_t *lock; /@ Private lock for this entity @/
Ipmip_timer_t timer; /@ Timer handle for doing timers @/
Ip_u32 my_ip_address; /@ IP Address of this entity @/
struct Ipmip_if *my_interface; /@ Interface this entity is on @/
};
struct Ipmip_my_context
{
Ipmip_context_t ipmip; /@ Basic IPMIP context @/
Ipmip_proc_t *my_proc_func; /@ Container for a process of some sort @/
Ipmip_context_id_t *my_identities; /@ My identity context @/
Ipmip_dhcp_node_t my_dhcp; /@ DHCP context registration handle @/
Ip_u32 my_dhcp_server_address; /@ DHCP server address @/
Ipmip_dhcp6_node_t my_dhcp6; /@ DHCPv6 context registration handle @/
struct Ip_in6_addr my_dhcp6_server_address; /@ DHCP6 server address @/
Ipmip_timer_lock_t *my_lock; /@ A global lock @/
}
struct Ipmip_my_context *my_init_func(Ipmip_proc_t *proc)
{
/@ Allocate my context; indicate the size of my overloaded structure @/
struct Ipmip_my_context *ctx = (struct Ipmip_my_context *)ipmip_context_alloc(proc, sizeof(*ctx), "mymip", IPCOM_LOG_DEBUG2, 10);
/@ Create any subcontext such as DHCP, CLI - see the appropriate module for information @/
/@ Create the identity structure - we've only setup a 16 bit identity field, so set the mask to 16 bits @/
ctx->my_identities = ipmip_context_id_create(ip_offsetof(struct Ipmip_my_entities, identity), 0xFFFF);
/@ Create a lock we can use for serialization. This lock will be used by various examples,
and one may want to create more locks in order to not cause bottlenecks. @/
ctx->my_lock = ipmip_timer_lock_alloc(&ctx->ipmip, proc, IP_NULL, IP_NULL);
/@ Start the context @/
ipmip_context_start(&ctx->ipmip, proc);
}
void my_stop_func(Ipmip_proc_t *proc, struct Ipmip_my_context *ctx)
{
/@ Stop the context @/
ipmip_context_stop(&ctx->ipmip, proc);
/@ Destroy the identity context @/
ipmip_context_id_destroy(ctx->my_identities);
/@ Destroy the big lock @/
ipmip_timer_lock_destroy(&ctx->ipmip, proc, ctx->my_lock);
/@ Destroy the context @/
ipmip_context_destroy(&ctx->ipmip, proc);
}
static void my_proc_func(struct Ipmip_my_context *ctx,
Ipmip_proc_t *proc,
void *extra_arg)
{
/@ We may continue to do what we do until we're told to stop @/
for (; proc->quit != IP_TRUE;)
{
ipcom_sleep(1);
}
}
IP_STATIC int
ipmip_my_attr_func_dump(int event,
struct Ipmip_my_context *ctx,
Ipmip_proc_t *proc,
Ipmip_cli_message_t *request,
struct Ipmip_my_entities *node)
{
/@ Was this function invoked properly? @/
if (event == IPMIP_TIMER_EVENT_RUN)
{
/@ Begin by locking down the identity containter @/
ipmip_context_id_lock(ctx->my_identities);
/@ Free the unique identifier and unreference the entity @/
ipmip_context_id_release(ctx->my_identities, node);
/@ Finish up by unlocking the identity containter @/
ipmip_context_id_unlock(ctx->my_identities);
/@ Free the lock @/
ipmip_timer_lock_destroy(&ctx->ipmip, proc, node->lock);
/@ Free the entity @/
ipcom_free(node);
}
/@ This timer is done - finalize processing @/
return IPMIP_TIMER_RET_DONE;
}
static void ipmip_my_entity_delete_foreach(struct Ipmip_my_context *ctx,
Ipmip_proc_t *proc,
struct Ipmip_my_entities *node,
void *unused1,
void *unused2)
{
/@ Schedule a destruction timer - we're holding the identity lock,
but we need to acquire the node's own lock as well. @/
ipmip_timer_request(&ctx->ipmip,
proc,
&node->timer,
node->lock,
(Ipmip_timer_func_t)ipmip_my_entity_delete,
node,
IP_NULL,
0);
}
void main(int argc, char *argv[])
{
/@ For threads started with ipmip_proc_start, the proc structure is allocated
automatically, for other types of threads such as main, we need to
allocate it manually @/
Ipmip_proc_t *proc = ipmip_proc_alloc();
struct Ipmip_my_context *ctx = my_init_func(proc);
struct Ipmip_my_entities *node;
/@ Start a new process, using the ipmip_proc_start method - Store its
process context handle so that we may kill it later @/
ctx->my_proc_func = ipmip_proc_start(&ctx->ipmip, proc, "my_proc_func", (Ipmip_proc_func_t)my_proc_func, IP_NULL);
/@ Create an entity of some sort @/
node = ipcom_calloc(1, sizeof(*node));
ipcom_strcpy(node->name, "my.name@my.domain");
/@ More or less all nodes in the MIP system requires a locking mechanism.
See ipmip_timer.h for more extensive explanations @/
node->lock = ipmip_timer_lock(&ctx->ipmip, proc, IP_NULL, IP_NULL);
/@ Initialize the timer @/
IPMIP_TIMER_INIT(&node->timer);
/@ Allocate an unique ID @/
/@ Begin by locking down the identity containter @/
ipmip_context_id_lock(ctx->my_identities);
/@ This function will initialize the identity variable, and reference the node @/
ipmip_context_id_allocate(ctx->idents, node);
/@ Finish up by unlocking the identity containter @/
ipmip_context_id_unlock(ctx->my_identities);
/@ Free all nodes allocated @/
/@ Begin by locking down the identity containter @/
ipmip_context_id_lock(ctx->my_identities);
/@ Invoke the callback for each entity in the identity table @/
ipmip_context_id_foreach(&ctx->ipmip,
proc,
ctx->my_identities,
(Ipmip_util_hash_foreach_t)ipmip_my_entity_delete_foreach,
IP_NULL,
IP_NULL);
/@ Finish up by unlocking the identity containter @/
ipmip_context_id_unlock(ctx->my_identities);
/@ Wait for the nodes to have terminated properly. They're terminated
by a timer, so we need to wait until its completed @/
ipmip_context_id_empty(ctx->my_identities. -1);
/@ Stop the thread and collect it @/
ipmip_proc_stop(&ctx->ipmip, proc, ctx->my_proc_func, IP_NULL, IP_NULL);
/@ Stop the context @/
my_stop_func(proc, ctx);
/@ Destroy the process context - If ipmip_proc_stop is used, @/
ipmip_proc_destroy(proc);
}
.CE
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipmip_ntop.h"
#include <ipcom_os.h>
#include <ipcom_hash.h>
#include <ipcom_list.h>
#include <private/ipmip_util.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmip_timer_context;
struct Ipmip_cli_context;
struct Ipmip_pktbuf_context;
struct Ipmip_pktbuf;
struct Ipmip_ntop;
struct Ipmip_netlink_handle;
struct Ipmip_netlink_context;
struct Ipmip_dhcp_context;
struct Ipmip_arp_context;
struct Ipmip_dhcp6_context;
struct Ipmip_pktbuf_pktaux;
struct Ipmip_dhcp6_embedded_server;
typedef struct Ipmip_context_log
{
Ipcom_mutex events_lock;
Ipcom_list events;
Ip_size_t events_max;
Ip_u32 loglevel;
} Ipmip_context_log_t;
typedef struct Ipmip_context_id
{
/**/
Ipcom_mutex identity_lock;
Ip_u32 identity;
Ipcom_hash *identity_table;
Ipcom_block identity_empty;
Ip_ptrdiff_t identity_offset;
Ip_u32 identity_mask;
} Ipmip_context_id_t;
/**/
typedef struct Ipmip_context
{
struct Ipmip_pktbuf_context *pktbuf;
struct Ipmip_timer_context *timer;
struct Ipmip_cli_context *cli;
struct Ipmip_netlink_context *nl;
#ifdef IPMIP_USE_INET
struct Ipmip_dhcp_context *dhcp;
struct Ipmip_arp_context *arp;
#endif
#ifdef IPMIP_USE_INET6
struct Ipmip_dhcp6_context *dhcp6;
#ifdef IP_PORT_LAS
struct Ipmip_dhcp6_embedded_server *dhcps6;
#endif
#endif
Ip_fd fd_ioctl;
struct Ipmip_netlink_handle *nl_req;
char *name;
int vr;
struct Ipmip_pktbuf_pktaux *pktaux;
/**/
/**/
Ipmip_context_log_t log;
} Ipmip_context_t;
/* Per thread specific information */
typedef struct Ipmip_proc
{
Ipmip_ntop_t ntop;
Ipcom_block proc_block;
Ip_bool quit;
Ip_pid_t pid;
union
{
Ip_u32 arg32;
} args;
} Ipmip_proc_t;
/**/
typedef void (*Ipmip_proc_func_t)
(
Ipmip_context_t *context,
Ipmip_proc_t *proc,
void *arg
);
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipmip_context_alloc - ipmip_context_alloc
*
* Allocate the mobility context. There exists only ONE context per mobility
* entity. The context contains information regarding timers, loglevels, history,
* packet buffers, open sockets and various sub-context functionalities such as
* DHCP, DHCPv6. This context is usually part of a larger entity specific
* context which will define additional funcitonaly beyond what the IPMIP module
* specifies.
*
* Parameters:
* \is
* \i proc
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \i size
* Total size of context.
* \ie
*
* RETURNS: The newly allocated packet context on success.
*
* ERRNO:
*
* NOMANUAL
*/
IP_GLOBAL Ipmip_context_t *ipmip_context_alloc
(
Ipmip_proc_t *proc,
Ip_size_t size,
const char *name,
int loglevel,
int evsize
);
/*******************************************************************************
*
* ipmip_context_destroy - ipmip_context_destroy
*
* Destroys the MIP context, and all sub-contexts allocated by it.
*
* Parameters:
* \is
* \i ctx
* The generic mobility singleton context for IPMIP. For each started mobility
* entity, there exists a mobility context which tracks configuration, system
* events, available features and started processes. The mobility context is
* created using ipmip_context_create(). See ipmip_context.h for more information
* regarding the mobility entity context singleton.
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* NOMANUAL
*/
IP_GLOBAL void ipmip_context_destroy
(
Ipmip_context_t *ctx,
Ipmip_proc_t *proc
);
/*******************************************************************************
*
* ipmip_context_stop - ipmip_context_stop
*
* Stop the context. Terminates all current processes, threads and activities
* controlled by the IPMIP context.
*
* Parameters:
* \is
* \i ctx
* The generic mobility singleton context for IPMIP. For each started mobility
* entity, there exists a mobility context which tracks configuration, system
* events, available features and started processes. The mobility context is
* created using ipmip_context_create(). See ipmip_context.h for more information
* regarding the mobility entity context singleton.
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* NOMANUAL
*/
IP_GLOBAL void ipmip_context_stop
(
Ipmip_context_t *ctx,
Ipmip_proc_t *proc
);
/*******************************************************************************
*
* ipmip_context_start - ipmip_context_start
*
* Start the context. Start the required processes, threads and event loops
* controlled by the IPMIP context.
*
* Parameters:
* \is
* \i ctx
* The generic mobility singleton context for IPMIP. For each started mobility
* entity, there exists a mobility context which tracks configuration, system
* events, available features and started processes. The mobility context is
* created using ipmip_context_create(). See ipmip_context.h for more information
* regarding the mobility entity context singleton.
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* NOMANUAL
*/
IP_GLOBAL void ipmip_context_start
(
Ipmip_context_t *ctx,
Ipmip_proc_t *proc
);
/*******************************************************************************
*
* ipmip_proc_start - ipmip_proc_start
*
* This method starts a new process and returns the process context for that
* newly started process. The process context contains a 'quit' indicator,
* which when set indicates that the mobility agent wants this process to
* exit in a controlled fashion.
*
* Parameters:
* \is
* \i ctx
* The generic mobility singleton context for IPMIP. For each started mobility
* entity, there exists a mobility context which tracks configuration, system
* events, available features and started processes. The mobility context is
* created using ipmip_context_create(). See ipmip_context.h for more information
* regarding the mobility entity context singleton.
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \i proc_name
* Name of the process
* \i func
* Thread start function
* \i arg
* Opaque argument
* \ie
*
* RETURNS: Thread context, if successful.
*
* ERRNO:
*
*/
IP_GLOBAL Ipmip_proc_t * ipmip_proc_start
(
Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
const char *proc_name,
Ipmip_proc_func_t func,
void *arg
);
/*******************************************************************************
*
* ipmip_proc_stop - ipmip_proc_stop
*
* Stop a specific process context and free the process context associated
* with it. Usually this function sets the 'quit' indicator in the
* process context and expects the process to see it.
* If that is not the case, such as that the process is waiting on a blocking
* call or any other such mechanism, it is possible to provide a wakeup function
* and opaque argument to the stop function. This wakeup function will be
* invoked at the proper location during the stop procedure. It is expected that
* the wakeup function interrupts whatever event the process is waiting for,
* and that it inspects the quit indicator and then exits accordingly.
*
* Parameters:
* \is
* \i ctx
* The generic mobility singleton context for IPMIP. For each started mobility
* entity, there exists a mobility context which tracks configuration, system
* events, available features and started processes. The mobility context is
* created using ipmip_context_create(). See ipmip_context.h for more information
* regarding the mobility entity context singleton.
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \i stop_proc
* Thread context to stop
* \i func
* Wakeup function
* \i arg
* Opaque argument
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
*/
IP_GLOBAL void ipmip_proc_stop
(
Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_proc_t *stop_proc,
Ipmip_proc_func_t func,
void *arg
);
/*******************************************************************************
*
* ipmip_proc_collect - ipmip_proc_collect
*
* See if a particular process has been stopped. If the process has indeed
* been stopped, the process context belonging to it will be freed by this
* function call.
*
* Parameters:
* \is
* \i ctx
* The generic mobility singleton context for IPMIP. For each started mobility
* entity, there exists a mobility context which tracks configuration, system
* events, available features and started processes. The mobility context is
* created using ipmip_context_create(). See ipmip_context.h for more information
* regarding the mobility entity context singleton.
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \i stop_proc
* Thread context
* \ie
*
* RETURNS: IP_TRUE if the process was collected.
*
* ERRNO:
*
*/
IP_GLOBAL Ip_bool ipmip_proc_collect
(
Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_proc_t *stop_proc
);
/*******************************************************************************
*
* ipmip_proc_destroy - ipmip_proc_destroy
*
* Destroy the process context and free all resources associated with it. Should
* only be used on process contexts which has been allocated manually by
* ipmip_proc_alloc. All other process contexts should be dealt with by
* ipmip_proc_stop or ipmip_proc_collect.
*
* Parameters:
* \is
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
*/
IP_GLOBAL void ipmip_proc_destroy
(
Ipmip_proc_t *proc
);
/*******************************************************************************
*
* ipmip_proc_alloc - ipmip_proc_alloc
*
* Creates a process context.
*
* Parameters:
*
* None.
*
* RETURNS: A process context on success
*
* ERRNO:
*
*/
IP_GLOBAL Ipmip_proc_t * ipmip_proc_alloc
(
void
);
/*******************************************************************************
*
* ipmip_context_id_create - ipmip_context_id_create
*
* Create an identity context. An identity context creates a hash table
* in which each object is guaranteed an unique identity value stored in the
* object offset provided in the create call.
*
* Parameters:
*
* \is
* \i offset
* The offset in the object where the identity is stored
* \i mask
* The mask to determine the size of identity
* \ie
*
* RETURNS: A new context
*
* ERRNO:
*
*/
IP_GLOBAL Ipmip_context_id_t * ipmip_context_id_create
(
Ip_ptrdiff_t offset,
Ip_u32 mask
);
/*******************************************************************************
*
* ipmip_context_id_destroy - ipmip_context_id_destroy
*
* Destroy an identity context
*
* Parameters:
*
* \is
* \i idctx
* The context to destroy
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
*/
IP_GLOBAL void ipmip_context_id_destroy
(
Ipmip_context_id_t *idctx
);
/*******************************************************************************
*
* ipmip_context_id_allocate - ipmip_context_id_allocate
*
* Allocate an identity value.If this object can be accessed simultaneously,
* you must lock it using ipmip_context_id_lock prior to the call
*
* Parameters:
*
* \is
* \i idctx
* Identity Context
* \i obj
* Object to allocate identity for
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
*/
IP_GLOBAL void ipmip_context_id_allocate
(
Ipmip_context_id_t *idctx,
void *obj
);
/*******************************************************************************
*
* ipmip_context_id_release - ipmip_context_id_release
*
* Release an identity value.If this object can be accessed simultaneously,
* you must lock it using ipmip_context_id_lock prior to the call
*
* Parameters:
*
* \is
* \i ctx
* Identity Context
* \i obj
* Object
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
*/
IP_GLOBAL void ipmip_context_id_release
(
Ipmip_context_id_t *idctx,
void *obj
);
/*******************************************************************************
*
* ipmip_context_id_get - ipmip_context_id_get
*
* Get an identity object. If this object can be accessed simultaneously,
* you must lock it using ipmip_context_id_lock prior to the call
*
* Parameters:
*
* \is
* \i ctx
* Identity Context
* \i ident
* Identity
* \ie
*
* RETURNS: The object allocating this identity or IP_NULL
*
* ERRNO:
*
*/
IP_GLOBAL void* ipmip_context_id_get
(
Ipmip_context_id_t *idctx,
Ip_u32 ident
);
/*******************************************************************************
*
* ipmip_context_id_empty - ipmip_context_id_empty
*
* Wait for the identity table to go empty. If a wait timeout is specified,
* the function while wait for at most wait_timeout milliseconds. If the
* context identity table is not empty by then, IP_FALSE will be returned.
*
* If -1 is specified, the function will wait indefinately.
*
* Parameters:
*
* \is
* \i ctx
* Identity Context
* \i wait_timeout
* Wait timeout in milliseconds, -1 specifies forever.
* \ie
*
* RETURNS: IP_TRUE if the identity context is empty
*
* ERRNO:
*
*/
IP_GLOBAL Ip_bool ipmip_context_id_empty
(
Ipmip_context_id_t *idctx,
int wait_timeout
);
/*******************************************************************************
*
* ipmip_context_id_foreach - ipmip_context_id_foreach
*
* Go through an identity table and invoke each object through the
* callback
*
* Parameters:
* \is
* \i ctx
* Context
* \i proc
* The process context associated with the currently executing thread. Each
* thread and/or process in MIP must have its own unique process context.
* If a process is started using ipmip_proc_start, the process context will
* be allocated automatically by the IPMIP framework. Otherwise it must
* be allocated using ipmip_proc_alloc().
* \i idctx
* Identity table
* \i func
* Object callback functions
* \i arg1
* Opaque argument 1
* \i arg2
* Opaque argument 2
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
*/
IP_GLOBAL void ipmip_context_id_foreach
(
struct Ipmip_context *ctx,
struct Ipmip_proc *proc,
Ipmip_context_id_t *idctx,
Ipmip_util_hash_foreach_t func,
void *arg1,
void *arg2
);
/*******************************************************************************
*
* ipmip_context_id_lock - ipmip_context_id_lock
*
* Lock an identity context. Identity context should always be locked during
* operations such as allocate, release, get or foreach. One should never
* attempt to unconditionally acquire other locks while holding the identity
* locks, since they are supposed to be atomic in a sense, only to be held
* to a bare minimum.
*
* Parameters:
*
* \is
* \i ctx
* Identity Context
* \ie
*
* SYNOPSIS
* \ss
* void ipmip_context_id_lock
* (
* Ipmip_context_id_t *ctx
* )
* \se
*
* RETURNS: No return value
*
* ERRNO:
*
*/
#define ipmip_context_id_lock(ctx) ipcom_mutex_lock((ctx)->identity_lock)
/*******************************************************************************
*
* ipmip_context_id_unlock - ipmip_context_id_unlock
*
* Unlock an identity context
*
* Parameters:
*
* \is
* \i ctx
* Identity Context
* \ie
*
* SYNOPSIS
* \ss
* void ipmip_context_id_unlock
* (
* Ipmip_context_id_t *ctx
* )
* \se
*
* RETURNS: No return value
*
* ERRNO:
*
*/
#define ipmip_context_id_unlock(ctx) ipcom_mutex_unlock((ctx)->identity_lock)
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/