Code Examples.
Code Examples.
The Event Service invovles communincation between pulishers and subscribers and this is accomplished over an event channel. Here we illustrate how a typical subscriber and publisher would look like emphasizing on the various API available with the Event Service.
The example is based on the event generation on a water mark hit in the Execution Object(EO). The event generated has attributes like the EO name, Library ID, Water Mark ID, Water Mark Type and Water Mark Value. The publisher will publish with some specific values for each of these event attributes. A subscriber can choose the particular attributes it is interested in say a particular EO with the name "COR". In our example we have take the NULL filter which ensures delivery of any event generated on water mark hit irrespective of the attributes to the subscriber.
Common defintions: The filter/pattern information should be shared between the subscriber and publisher. These are passed as byte streams to Event Service and it is the responsibility of application to ensure these are endian neurtal by using marshalling (XDR) or some such mechanism. This would make it possible to filter events across different platforms.
typedef enum{
CL_EO_LIB_ID_OSAL,
CL_EO_LIB_ID_MEM,
CL_EO_LIB_ID_HEAP,
CL_EO_LIB_ID_BUFFER,
CL_EO_LIB_ID_TIMER,
CL_EO_LIB_ID_IOC,
CL_EO_LIB_ID_RMD,
CL_EO_LIB_ID_EO,
CL_EO_LIB_ID_RES,
CL_EO_LIB_ID_POOL = CL_EO_LIB_ID_RES,
CL_EO_LIB_ID_CPM,
CL_EO_LIB_ID_MAX
} ClEoLibIdT;
Subscriber Side:
Typical Event Service would provide with three different handles. The user may want to group them up as below:
typedef struct ClSubsEventInfo
{
} ClSubsEventInfoT;
static ClSubsEventInfoT gSubsEventInfo;
ClHandleT ClEventChannelHandleT
The type of a handle to an open event channel.
Definition: clEventApi.h:164
ClHandleT ClEventInitHandleT
The type of the handle supplied by the EM to an EO during the initialization of the EM library.
Definition: clEventApi.h:153
ClHandleT ClEventHandleT
The type of a handle to an event.
Definition: clEventApi.h:158
If the application chooses to open the channel asynchronously then it needs to register a callback that shall be invoked on the creation of the channel. A typical callback would contain the subcription calls or event publish related calls. This has been illustrated in the publisher later.
void clSubsAsyncChannelOpenCb(ClInvocationT invocation,
{
clOsalPrintf(
"*******************************************************\n");
clOsalPrintf(
"************* Async Channel Open Callback *************\n");
clOsalPrintf(
"*******************************************************\n");
clOsalPrintf(
" Channel Handle : %p\n", (ClPtrT)channelHandle);
clOsalPrintf(
"*******************************************************\n");
{
goto failure;
}
CL_EVENT_DEFAULT_SUBS_FILTER, UNIQUE_SUBSCRIPTION_ID,
"User Specified Argument (cookie) for the event delivery callback");
{
goto failure;
}
failure:
return;
}
ClUint32T ClRcT
Clovis return code type.
Definition: clCommon.h:168
#define CL_OK
Every thing is OK.
Definition: clCommonErrors.h:68
ClRcT clEventSubscribe(CL_IN ClEventChannelHandleT channelHandle, CL_IN const ClEventFilterArrayT *pFilters, CL_IN ClEventSubscriptionIdT subscriptionId, CL_IN void *pCookie)
Subscribes to an event identified by an event type (filter).
ClRcT clOsalPrintf(const ClCharT *fmt,...)
Prints to the standard output.
The subscriber is required to register a callback during the Event Library initialize which is to invoked when an event is delivered. For our example the callback is as follows:
{
ClPtrT pCookie = NULL;
ClPtrT pEventData = NULL;
ClUint8T *pEventPayload = NULL;
if (pEventData == NULL)
{
clOsalPrintf(
"Allocation for event data failed. rc[%#X]\n", rc);
goto failure;
}
{
goto failure;
}
pEventPayload = pEventData;
{
goto failure;
}
&retentionTime, &publisherName,
&publishTime, &eventId);
{
goto failure;
}
clOsalPrintf(
"-------------------------------------------------------\n");
clOsalPrintf(
"!!!!!!!!!!!!!!! Event Delivery Callback !!!!!!!!!!!!!!!\n");
clOsalPrintf(
"-------------------------------------------------------\n");
retentionTime);
CL_WM_HIGH_LIMIT) ? "HIGH" : "LOW");
clOsalPrintf(
"-------------------------------------------------------\n");
failure:
return;
}
ClInt64T ClTimeT
Time duration specified in nanoseconds.
Definition: clCommon.h:154
ClUint64T ClSizeT
Definition: clCommon.h:157
ClRcT clEventCookieGet(CL_IN ClEventHandleT eventHandle, CL_OUT void **ppCookie)
Returns the cookie.
ClRcT clEventFree(CL_IN ClEventHandleT eventHandle)
Frees an event header.
ClRcT clEventAttributesGet(CL_IN ClEventHandleT eventHandle, CL_IN ClEventPatternArrayT *pPatternArray, CL_OUT ClEventPriorityT *pPriority, CL_OUT ClTimeT *pRetentionTime, CL_OUT ClNameT *pPublisherName, CL_OUT ClTimeT *pPublishTime, CL_OUT ClEventIdT *pEventId)
Returns the event attributes.
ClUint8T ClEventPriorityT
Event priority type - it ranges from CL_EVENT_LOWEST_PRIORITY to CL_EVENT_HIGHEST_PRIORITY.
Definition: clEventApi.h:121
ClUint32T ClEventSubscriptionIdT
The type of an identifier for a particular subscription by a particular EO on a particular event chan...
Definition: clEventApi.h:171
ClUint64T ClEventIdT
The type of an event identifier.
Definition: clEventApi.h:115
ClRcT clEventDataGet(CL_IN ClEventHandleT eventHandle, CL_INOUT void *pEventData, CL_INOUT ClSizeT *pEventDataSize)
Returns data associated with an earlier event.
void clHeapFree(CL_IN ClPtrT pAddress)
Frees a pre-allocated memory.
ClPtrT clHeapAllocate(CL_IN ClUint32T size)
Allocates memory of the requested size.
A name.
Definition: clCommon.h:197
ClUint16T length
Length of the name in bytes excluding '\0'.
Definition: clCommon.h:199
ClCharT value[CL_MAX_NAME_LENGTH]
Actual name represented as a null terminated ASCII string.
Definition: clCommon.h:201
ClSizeT patternSize
Actual size of the buffer allocated to receive the pattern value.
Definition: clEventApi.h:286
ClUint8T * pPattern
Pointer to a buffer where the pattern value will be copied.
Definition: clEventApi.h:291
The type of an event pattern array.
Definition: clEventApi.h:299
ClEventPatternT * pPatterns
Pointer to a buffer where the array of pattern will be copied.
Definition: clEventApi.h:314
Any component that wishes to be a subscriber has to initialize the Event Library with appropriate arguments. The following code snippet shows how Event Library is initialized and set for the subscription. Typically, the following function would reside in the clCompAppInitialize() registered in the clEoConfig structure of an EO. There could be multiple subscriptions depending on the requirement each with a unique subscription id (unique per initialization of Event Library).
static ClRcT clSubsEventLibrayInitialize(
void)
{
{
NULL,
clSubEoEventWaterMarkCb,
};
&version);
{
goto failure;
}
&gSubsEventInfo.channelHandle);
{
goto init_done;
}
CL_EVENT_DEFAULT_SUBS_FILTER, UNIQUE_SUBSCRIPTION_ID,
"User Specified Argument (cookie) for the event delivery callback");
{
goto channel_opened;
}
channel_opened:
init_done:
failure:
return rc;
}
#define CL_EO_EVENT_CHANNEL_NAME
The Event Channel on which the Water Mark Notification is published.
Definition: clEoApi.h:334
ClRcT clEventFinalize(CL_IN ClEventInitHandleT evtHandle)
Finalizes EM library.
ClRcT clEventInitialize(CL_OUT ClEventInitHandleT *pEvtHandle, CL_IN const ClEventCallbacksT *pEvtCallbacks, CL_INOUT ClVersionT *pVersion)
Initializes EM library.
#define CL_EVENT_CHANNEL_SUBSCRIBER
Opens an event channel for subscribing events.
Definition: clEventApi.h:77
ClRcT clEventChannelOpen(CL_IN ClEventInitHandleT evtHandle, CL_IN const ClNameT *pEvtChannelName, CL_IN ClEventChannelOpenFlagsT evtChannelOpenFlag, CL_IN ClTimeT timeout, CL_OUT ClEventChannelHandleT *pChannelHandle)
Opens an event channel.
ClRcT clEventChannelClose(CL_IN ClEventChannelHandleT channelHandle)
Closes an event channel.
#define CL_EVENT_VERSION
Latest Supported SAF Version for Event Service.
Definition: clEventApi.h:102
ClUint8T ClEventChannelOpenFlagsT
Event Channel open flag.
Definition: clEventApi.h:140
#define CL_EVENT_LOCAL_CHANNEL
Opens a local event channel.
Definition: clEventApi.h:67
#define CL_RMD_DEFAULT_TIMEOUT
Default timeout for the RMD call - 10 seconds QNX has a traffic shaper leaky bucket.
Definition: clRmdApi.h:118
Version Information for various services.
Definition: clCommon.h:250
The callback structure supplied by an EO to the EM containing the callback functions that can be invo...
Definition: clEventApi.h:244
The Event Library is typically finalized from within clCompAppTerminate() registered with the Component Manager (CPM). The following code snippet illustrates the steps involved in finalization of a subscriber.
static ClRcT clSubsEventLibrayFinalize(
void)
{
UNIQUE_SUBSCRIPTION_ID);
{
}
{
}
{
}
}
ClRcT clEventUnsubscribe(CL_IN ClEventChannelHandleT channelHandle, CL_IN ClEventSubscriptionIdT subscriptionId)
Unsubscribes from an event.
Publisher Side:
The Publisher would unlike a subscriber allocate events, set their attributes appropriately and publish them as illustrated below:
static ClRcT clPubsTriggerEvent(ClEoLibIdT libId, ClWaterMarkIdT wmId,
ClUint32T wmValue, ClEoWaterMarkFlagT wmFlag)
{
ClNameT publisherName = {
sizeof(CL_EVENT_PUBLISHER_NAME)-1,
CL_EVENT_PUBLISHER_NAME};
0,
patterns
};
&gPubsEventInfo.eventHandle);
{
goto failure;
}
patterns[1].
pPattern = (ClUint8T *)&libId;
patterns[2].
pPattern = (ClUint8T *)&wmId;
patterns[3].
pPattern = (ClUint8T *)&wmFlag;
patterns[4].
pPattern = (ClUint8T *)(&wmValue);
{
goto event_allocated;
}
"Event Payload passed in endian neutral way",
sizeof("Event Payload passed in endian neutral way.")-1,
&eventId);
{
goto event_allocated;
}
event_allocated:
{
}
failure:
return rc;
}
#define CL_SIZEOF_ARRAY(__ArrayName__)
The following macros returns the number of items in the given array.
Definition: clCommon.h:103
#define CL_EO_NAME
Gives the name of the Execution Object.
Definition: clEoConfigApi.h:77
ClRcT clEventAttributesSet(CL_IN ClEventHandleT eventHandle, CL_IN const ClEventPatternArrayT *pPatternArray, CL_IN ClEventPriorityT priority, CL_IN ClTimeT retentionTime, CL_IN const ClNameT *pPublisherName)
Sets the event attributes.
ClRcT clEventPublish(CL_IN ClEventHandleT eventHandle, CL_IN const void *pEventData, CL_IN ClSizeT eventDataSize, CL_OUT ClEventIdT *pEventId)
Publishes an event.
#define CL_EVENT_HIGHEST_PRIORITY
Highest priority.
Definition: clEventApi.h:92
ClRcT clEventAllocate(CL_IN ClEventChannelHandleT channelHandle, CL_OUT ClEventHandleT *pEventHandle)
Allocates an event header.
An Event pattern may contain a name (for example: a process name, checkpoint name,...
Definition: clEventApi.h:276
Like in the subscriber the publisher needs to do the Event Library Initialize as suggested before. In publisher we open the channel asynchronously, the callback for which is as below:
void clPubsAsyncChannelOpenCb(ClInvocationT invocation,
{
clOsalPrintf(
"*******************************************************\n");
clOsalPrintf(
"************* Async Channel Open Callback *************\n");
clOsalPrintf(
"*******************************************************\n");
clOsalPrintf(
" Channel Handle : %p\n", (ClPtrT)channelHandle);
clOsalPrintf(
"*******************************************************\n");
{
clOsalPrintf(
"clEventChannelOpenAsync() failed [%#X]\n",rc);
goto failure;
}
gPubsEventInfo.channelHandle = channelHandle;
rc = clPubsTriggerEvent(CL_EO_LIB_ID_HEAP, CL_WM_HIGH, CL_WM_HIGH_LIMIT,
CL_WM_LOW_LIMIT);
{
goto channel_opened;
}
channel_opened:
failure:
return;
}
Much of the code is similar between the subscriber and publisher as can be seen below. The only difference being a publisher may optionally choose to be a subscriber also in which case it will need to register an event delivery callback. Note that event publish related API that appear in channel open callback above would appear right after the channel open if it were synchrounous. The event can be allocated each time it is published or it can be re-used with special care taken about protection in multi threaded environment when the event handle is shared between the threads.
typedef struct ClPubsEventInfo
{
} ClPubsEventInfoT;
static ClPubsEventInfoT gPubsEventInfo;
static ClRcT clPubsEventLibrayInitialize(
void)
{
{
clPubsAsyncChannelOpenCb,
NULL,
};
ClInvocationT invocation = UNIQUE_INVOCATION_ID;
&evtCallbacks, &version);
{
goto failure;
}
&channelName, evtFlags);
{
goto init_done;
}
init_done:
failure:
return rc;
}
static ClRcT clPubsEventLibrayFinalize(
void)
{
{
}
{
}
}
ClRcT clEventChannelOpenAsync(CL_IN ClEventInitHandleT evtHandle, CL_IN ClInvocationT invocation, CL_IN const ClNameT *pEvtChannelName, CL_IN ClEventChannelOpenFlagsT channelOpenFlags)
Opens an event channel asynchronously.
#define CL_EVENT_CHANNEL_PUBLISHER
Opens an event channel for publishing events.
Definition: clEventApi.h:82