/* $Id: event_lib.c,v 1.8.2.4 2004/11/12 00:12:33 yixiong Exp $ */
/*
* event_lib.c: source file for event library
*
* Copyright (C) 2004 Forrest,Zhao <forrest.zhao@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <clplumbing/cl_signal.h>
#include <event.h>
int global_debug=0;
int global_verbose=0;
static GHashTable *evt_handle_hash = NULL;
static GHashTable *evt_channel_hash = NULL;
static GHashTable *evt_event_hash = NULL;
static GHashTable *subscription_global = NULL;
#define RELEASE_CODE 'A'
#define MAJOR_VERSION 1
#define MINOR_VERSION 1
typedef struct evt_event_handle_s {
SaSizeT event_size;
void *patternArray;
SaUint8T priority;
SaTimeT retentionTime;
SaNameT publisherName;
SaTimeT publishTime;
SaEvtEventIdT eventId;
void *eventData;
SaSizeT eventDataSize;
SaEvtChannelHandleT ch_handle;
SaEvtSubscriptionIdT subscription_id;
SaEvtEventIdT evtId;
SaEvtChannelHandleT channelId;
struct evt_event_handle_s *next;
int set_flag;
} evt_event_handle;
struct queue_head {
evt_event_handle *head;
evt_event_handle *tail;
};
struct open_channel_reply_queue {
struct open_channel_reply *head;
struct open_channel_reply *tail;
};
struct event_queue_s {
SaSizeT event_number;
struct queue_head queue[SA_EVT_HIGHEST_PRIORITY+1];
SaSizeT reply_number;
struct open_channel_reply_queue open_ch_reply_queue;
};
typedef struct evt_handle_s {
struct IPC_CHANNEL *ch;
SaSelectionObjectT selectionObject;
SaEvtCallbacksT callbacks;
GHashTable *evt_channel_hash;
struct event_queue_s *event_queue;
} evt_handle;
typedef struct evt_channel_handle_s{
SaNameT channelName;
struct IPC_CHANNEL *ch;
SaSelectionObjectT selectionObject;
SaEvtEventIdT channelId;
GHashTable *event_handle_hash;
GHashTable *subscription_hash;
SaEvtHandleT evt_handle;
SaInvocationT invocation;
SaEvtChannelOpenFlagsT open_flags;
void *ch_instance;
} evt_channel_handle;
typedef struct evt_subscription_s {
const SaNameT *channelName;
SaEvtEventFilterArrayT *filters;
SaEvtEventIdT channelId;
SaEvtSubscriptionIdT subscriptionId;
} evt_subscription;
struct open_channel_reply{
SaNameT channel_name;
SaEvtChannelHandleT clt_ch_handle;
void* ch_instance;
SaErrorT ret_code;
struct open_channel_reply *next;
};
struct publish_reply{
SaEvtEventHandleT eventHandle;
SaErrorT ret_code;
SaEvtEventIdT event_id;
};
struct clear_retention_time_reply{
SaNameT channel_name;
SaEvtEventIdT event_id;
SaErrorT ret_code;
};
struct daemon_msg {
enum evt_type msg_type;
union {
struct open_channel_reply *open_ch_reply;
struct publish_reply *pub_reply;
struct clear_retention_time_reply *clear_retention_reply;
evt_event_handle *event;
} private;
};
static struct sa_handle_database evt_handle_database;
static struct sa_handle_database ch_handle_database;
static struct sa_handle_database event_handle_database;
static void init_global_variable(void)
{
evt_handle_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
evt_channel_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
evt_event_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
subscription_global = g_hash_table_new(g_direct_hash, g_direct_equal);
evt_handle_database.handle_count = 0;
ch_handle_database.handle_count = 0;
event_handle_database.handle_count = 0;
return;
}
static SaErrorT send_to_evt_daemon(struct IPC_CHANNEL *ch,
void *msg, SaSizeT msg_size)
{
struct IPC_MESSAGE Msg;
Msg.msg_body = msg;
Msg.msg_len = msg_size;
Msg.msg_done = NULL;
Msg.msg_private = NULL;
Msg.msg_ch = ch;
if(ch->ops->send(ch, &Msg) != IPC_OK){
return SA_ERR_LIBRARY;
}
return SA_OK;
}
static SaErrorT send_evt_init(struct IPC_CHANNEL *ch)
{
SaSizeT msg_size;
SaUint8T *tmp_char;
void *msg;
msg_size = 1;
msg = g_malloc(msg_size);
tmp_char = (SaUint8T *)msg;
*(tmp_char) = EVT_INITIALIZE;
printf("%d", *(tmp_char));
send_to_evt_daemon(ch, msg, msg_size);
return SA_OK;
}
static void free_event(evt_event_handle *event_hd);
SaErrorT
saEvtInitialize(SaEvtHandleT *evtHandle,
const SaEvtCallbacksT *callbacks,
SaVersionT *version)
{
struct IPC_CHANNEL *ch;
evt_handle *evt_hd;
GHashTable *attrs, *channel_hash;
char path[] = IPC_PATH_ATTR;
char sockpath[] = EVTFIFO;
struct event_queue_s *event_queue;
static int init = 0;
if((evtHandle == NULL) || (callbacks == NULL) || (version == NULL)){
return SA_ERR_INVALID_PARAM;
}
if(init == 0){
init_global_variable();
init++;
}
if((version->releaseCode == RELEASE_CODE) &&
(MAJOR_VERSION >= version->major)){
version->major = MAJOR_VERSION;
version->minor = MINOR_VERSION;
}else{
version->releaseCode = RELEASE_CODE;
version->major = MAJOR_VERSION;
version->minor = MINOR_VERSION;
return SA_ERR_VERSION;
}
if(get_handle(&evt_handle_database, evtHandle) != SA_OK)
return SA_ERR_NO_MEMORY;
evt_hd = (evt_handle *)g_malloc(sizeof(evt_handle));
if (!evt_hd){
put_handle(&evt_handle_database, *evtHandle);
return SA_ERR_NO_MEMORY;
}
channel_hash = g_hash_table_new(g_direct_hash,g_direct_equal);
if(!channel_hash){
g_free(evt_hd);
put_handle(&evt_handle_database, *evtHandle);
return SA_ERR_NO_MEMORY;
}
event_queue = (struct event_queue_s *)g_malloc0(
sizeof(struct event_queue_s));
attrs = g_hash_table_new(g_str_hash,g_str_equal);
if(!attrs){
g_free(evt_hd);
put_handle(&evt_handle_database, *evtHandle);
g_hash_table_destroy(channel_hash);
return SA_ERR_NO_MEMORY;
}
g_hash_table_insert(attrs, path, sockpath);
ch = ipc_channel_constructor(IPC_DOMAIN_SOCKET, attrs);
g_hash_table_destroy(attrs);
if(!ch || ch->ops->initiate_connection(ch) != IPC_OK){
g_free(evt_hd);
put_handle(&evt_handle_database, *evtHandle);
g_hash_table_destroy(channel_hash);
return SA_ERR_LIBRARY;
}
ch->ops->set_recv_qlen(ch, 0);
if(send_evt_init(ch) != SA_OK){
g_free(evt_hd);
put_handle(&evt_handle_database, *evtHandle);
g_hash_table_destroy(channel_hash);
ch->ops->destroy(ch);
return SA_ERR_LIBRARY;
}
evt_hd->ch = ch;
evt_hd->selectionObject = ch->ops->get_recv_select_fd(ch);
evt_hd->callbacks.saEvtChannelOpenCallback =
callbacks->saEvtChannelOpenCallback;
evt_hd->callbacks.saEvtEventDeliverCallback =
callbacks->saEvtEventDeliverCallback;
evt_hd->evt_channel_hash = channel_hash;
evt_hd->event_queue = event_queue;
g_hash_table_insert(evt_handle_hash, (gpointer)*evtHandle, evt_hd);
return SA_OK;
}
static void read_normal_event(void *msg, struct daemon_msg *ret)
{
evt_event_handle *event;
SaSizeT publisher_len;
SaUint8T *tmp_char;
event = (evt_event_handle *)g_malloc(sizeof(evt_event_handle));
ret->private.event = event;
tmp_char = (SaUint8T *)msg;
tmp_char++;
memcpy(&(event->channelId), tmp_char, sizeof(SaEvtChannelHandleT));
tmp_char += sizeof(SaEvtChannelHandleT);
memcpy(&(event->subscription_id), tmp_char, sizeof(SaEvtSubscriptionIdT));
tmp_char += sizeof(SaEvtSubscriptionIdT);
memcpy(&(event->event_size), tmp_char, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
event->patternArray = g_malloc(event->event_size);
memcpy(event->patternArray, tmp_char, event->event_size);
tmp_char += event->event_size;
event->priority = *(tmp_char);
tmp_char++;
memcpy(&(event->retentionTime), tmp_char, sizeof(SaTimeT));
tmp_char += sizeof(SaTimeT);
memcpy(&(publisher_len), tmp_char, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
event->publisherName.length = publisher_len;
memcpy(event->publisherName.value, tmp_char, publisher_len);
event->publisherName.value[publisher_len] = '\0';
tmp_char += publisher_len;
memcpy(&(event->publishTime), tmp_char, sizeof(SaTimeT));
tmp_char += sizeof(SaTimeT);
memcpy(&(event->eventId), tmp_char, sizeof(SaEvtEventIdT));
tmp_char += sizeof(SaEvtEventIdT);
memcpy(&(event->eventDataSize), tmp_char, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
event->eventData = g_malloc(event->eventDataSize);
memcpy(event->eventData, tmp_char, event->eventDataSize);
return;
}
static void read_ch_open_reply(void *msg, struct daemon_msg *ret)
{
SaUint8T *tmp_char;
SaSizeT str_len;
struct open_channel_reply *open_ch_reply;
open_ch_reply = (struct open_channel_reply *)g_malloc(
sizeof(struct open_channel_reply));
ret->private.open_ch_reply = open_ch_reply;
tmp_char = (SaUint8T *)msg;
tmp_char++;
memcpy(&(str_len), tmp_char, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
open_ch_reply->channel_name.length = str_len;
memcpy(open_ch_reply->channel_name.value, tmp_char, str_len);
open_ch_reply->channel_name.value[str_len] = '\0';
tmp_char += str_len;
memcpy(&(open_ch_reply->clt_ch_handle), tmp_char, sizeof(SaEvtChannelHandleT));
tmp_char += sizeof(SaEvtChannelHandleT);
memcpy(&(open_ch_reply->ch_instance), tmp_char, sizeof(void *));
tmp_char += sizeof(void *);
memcpy(&(open_ch_reply->ret_code), tmp_char, sizeof(SaErrorT));
return;
}
static void read_publish_reply(void *msg, struct daemon_msg *ret)
{
struct publish_reply *pub_reply;
SaUint8T *tmp_char;
pub_reply = (struct publish_reply *)g_malloc(
sizeof(struct publish_reply));
ret->private.pub_reply = pub_reply;
tmp_char = (SaUint8T *)msg;
tmp_char++;
memcpy(&(pub_reply->eventHandle), tmp_char, sizeof(SaEvtEventHandleT));
tmp_char += sizeof(SaEvtEventHandleT);
memcpy(&(pub_reply->event_id), tmp_char, sizeof(SaEvtEventIdT));
tmp_char += sizeof(SaEvtEventIdT);
memcpy(&(pub_reply->ret_code), tmp_char, sizeof(SaErrorT));
return;
}
static void read_clear_retention_reply(void *msg, struct daemon_msg *ret)
{
struct clear_retention_time_reply *clear_reply;
SaUint8T *tmp_char;
SaSizeT str_len;
clear_reply = (struct clear_retention_time_reply *)g_malloc(
sizeof(struct clear_retention_time_reply));
ret->private.clear_retention_reply = clear_reply;
tmp_char = (SaUint8T *)msg;
tmp_char++;
memcpy(&str_len, tmp_char, sizeof(SaSizeT));
clear_reply->channel_name.length = str_len;
tmp_char += sizeof(SaSizeT);
memcpy(clear_reply->channel_name.value, tmp_char, str_len);
clear_reply->channel_name.value[str_len] = '\0';
tmp_char += str_len;
memcpy(&(clear_reply->event_id), tmp_char, sizeof(SaEvtEventIdT));
tmp_char += sizeof(SaEvtEventIdT);
memcpy(&(clear_reply->ret_code), tmp_char, sizeof(SaErrorT));
return;
}
static struct daemon_msg *read_from_ipc(IPC_Channel *ch)
{
IPC_Message* ipc_msg;
char* msg_type;
struct daemon_msg *ret;
ret = (struct daemon_msg *)g_malloc(sizeof(struct daemon_msg));
ch->ops->is_message_pending(ch);
if(ch->ops->recv(ch, &ipc_msg) != IPC_OK){
return NULL;
}
msg_type = (char *)ipc_msg->msg_body;
ret->msg_type = *(msg_type);
printf("the msg type is: %d\n", ret->msg_type);
switch(*(msg_type)){
case EVT_NORMAL_EVENT:
read_normal_event(ipc_msg->msg_body, ret);
break;
case EVT_CH_OPEN_REPLY_FROM_DAEMON:
read_ch_open_reply(ipc_msg->msg_body, ret);
break;
case EVT_PUBLISH_REPLY:
read_publish_reply(ipc_msg->msg_body, ret);
break;
case EVT_CLEAR_RETENTION_TIME_REPLY:
read_clear_retention_reply(ipc_msg->msg_body, ret);
break;
default:
break;
}
ipc_msg->msg_done(ipc_msg);
return ret;
}
static SaErrorT append_to_event_queue(struct event_queue_s *event_queue,
evt_event_handle *event_hd)
{
SaUint8T priority;
struct queue_head *queue;
priority = event_hd->priority;
if(priority > SA_EVT_LOWEST_PRIORITY)
{
return SA_ERR_INVALID_PARAM;
}
event_queue->event_number++;
queue = &(event_queue->queue[priority]);
if((queue->head == NULL) && (queue->tail == NULL)){
queue->head = event_hd;
queue->tail = event_hd;
}else{
queue->tail->next = event_hd;
queue->tail = event_hd;
}
return SA_OK;
}
static SaErrorT append_to_reply_queue(struct event_queue_s *event_queue,
struct open_channel_reply *open_ch_reply)
{
event_queue->reply_number++;
if((event_queue->open_ch_reply_queue.tail == NULL) &&
(event_queue->open_ch_reply_queue.head == NULL)){
event_queue->open_ch_reply_queue.head = open_ch_reply;
event_queue->open_ch_reply_queue.tail = open_ch_reply;
}else{
event_queue->open_ch_reply_queue.tail->next = open_ch_reply;
event_queue->open_ch_reply_queue.tail = open_ch_reply;
}
return SA_OK;
}
SaErrorT
saEvtChannelOpen(const SaEvtHandleT evtHandle, const SaNameT *channelName,
SaEvtChannelOpenFlagsT channelOpenFlags, SaTimeT timeout,
SaEvtChannelHandleT *channelHandle)
{
evt_handle *evt_hd;
evt_channel_handle *evt_channel_hd;
GHashTable *channel_hash;
struct IPC_CHANNEL *ch;
fd_set rset;
struct timeval time_out;
int fd, select_ret;
SaEvtChannelHandleT channel_handle;
void *msg;
struct daemon_msg *msg_reply;
evt_event_handle *event_hd;
struct open_channel_reply *open_ch_reply;
SaSizeT msg_len, str_len;
SaUint8T *tmp_char;
if((channelHandle == NULL) || (channelName == NULL)){
return SA_ERR_INVALID_PARAM;
}
if(channelOpenFlags > 7){
return SA_ERR_BAD_FLAGS;
}
evt_hd = (evt_handle *)g_hash_table_lookup(evt_handle_hash,
(gpointer)evtHandle);
if( evt_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
ch = evt_hd->ch;
channel_hash = evt_hd->evt_channel_hash;
evt_channel_hd = (evt_channel_handle *)g_malloc(
sizeof(evt_channel_handle));
if (!evt_channel_hd)
return SA_ERR_NO_MEMORY;
if(get_handle(&ch_handle_database, &channel_handle) != SA_OK){
g_free(evt_channel_hd);
return SA_ERR_LIBRARY;
}
/*send channel_open request */
str_len = channelName->length;
msg_len = 1+sizeof(SaSizeT)+str_len+sizeof(SaEvtChannelHandleT)
+sizeof(SaEvtChannelOpenFlagsT);
msg = g_malloc(msg_len);
if(msg == NULL){
return SA_ERR_NO_MEMORY;
}
tmp_char = (SaUint8T *)msg;
*tmp_char = EVT_OPEN_EVENT_CHANNEL;
tmp_char++;
memcpy(tmp_char, &str_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
strncpy(tmp_char, channelName->value, str_len);
tmp_char += str_len;
memcpy(tmp_char, &(channel_handle), sizeof(SaEvtChannelHandleT));
tmp_char += sizeof(SaEvtChannelHandleT);
memcpy(tmp_char, &(channelOpenFlags), sizeof(SaEvtChannelOpenFlagsT));
send_to_evt_daemon(evt_hd->ch, msg, msg_len);
/* sleep(1); */
g_free(msg);
/*wait for reply */
fd = evt_hd->selectionObject;
time_out.tv_sec = 0;
time_out.tv_usec = timeout;
/*if msg_type is normal event, buffer it and continue */
/*if msg_type is open_channel_reply, break */
for(;;){
FD_ZERO(&rset);
FD_SET(fd, &rset);
select_ret = select(fd + 1, &rset, NULL,NULL, NULL);
if(select_ret == -1){
/*perror("select"); */
return SA_ERR_LIBRARY;
}else if(select_ret == 0){
return SA_ERR_TIMEOUT;
}
msg_reply = read_from_ipc(ch);
if(msg_reply == NULL){
printf("received NULL msg from daemon\n");
return 0;
}
if(msg_reply->msg_type == EVT_CH_OPEN_REPLY_FROM_DAEMON){
if(channel_handle ==
msg_reply->private.open_ch_reply->clt_ch_handle){
if(msg_reply->private.open_ch_reply->ret_code
== SA_OK){
break;
}else{
return msg_reply->private.open_ch_reply->ret_code;
}
}else{
/*update timeout, continue */
}
}else if(msg_reply->msg_type == EVT_NORMAL_EVENT) {
event_hd = msg_reply->private.event;
append_to_event_queue(evt_hd->event_queue, event_hd);
/*TODO: update timeout, continue */
}else if(msg_reply->msg_type == EVT_ASYN_CH_OPEN_REPLY_FROM_DAEMON)
{
open_ch_reply = msg_reply->private.open_ch_reply;
append_to_reply_queue(evt_hd->event_queue,
open_ch_reply);
}else
{
/*update timeout, continue */
/*error msg */
}
}
/*if open evt_channel succeed */
evt_channel_hd->channelName.length = str_len;
strncpy(evt_channel_hd->channelName.value, channelName->value, str_len);
evt_channel_hd->evt_handle = evtHandle;
evt_channel_hd->ch = evt_hd->ch;
evt_channel_hd->selectionObject = fd;
evt_channel_hd->open_flags = channelOpenFlags;
evt_channel_hd->ch_instance =
msg_reply->private.open_ch_reply->ch_instance;
evt_channel_hd->event_handle_hash = g_hash_table_new(g_direct_hash,
g_direct_equal);
evt_channel_hd->subscription_hash = g_hash_table_new(g_direct_hash,
g_direct_equal);
g_hash_table_insert(channel_hash, (gpointer)channel_handle,
evt_channel_hd);
g_hash_table_insert(evt_channel_hash, (gpointer)channel_handle,
evt_channel_hd);
*(channelHandle) = channel_handle;
return SA_OK;
}
static void free_open_ch_reply(struct open_channel_reply *open_ch_reply)
{
g_free(open_ch_reply);
return;
}
static void free_event_queue(struct event_queue_s *event_queue)
{
SaSizeT i;
struct queue_head *queue;
evt_event_handle *event_tmp;
struct open_channel_reply *open_ch_reply;
if(event_queue->event_number != 0){
for(i=SA_EVT_HIGHEST_PRIORITY;i<=SA_EVT_LOWEST_PRIORITY;i++){
queue = &(event_queue->queue[i]);
while(queue->head != NULL){
event_tmp = queue->head;
queue->head = event_tmp->next;
free_event(event_tmp);
}
g_free(queue);
}
}
if(event_queue->reply_number != 0){
while(event_queue->open_ch_reply_queue.head != NULL){
open_ch_reply = event_queue->open_ch_reply_queue.head;
event_queue->open_ch_reply_queue.head =
open_ch_reply->next;
free_open_ch_reply(open_ch_reply);
}
}
g_free(event_queue);
}
static void free_event(evt_event_handle *event_hd)
{
/*free patternArray, publisherName, then free event_hd */
g_free(event_hd->patternArray);
g_free(event_hd->eventData);
g_free(event_hd);
return;
}
static void free_subscription_resource(gpointer key,
gpointer value,
gpointer user_data)
{
GHashTable *sub_hash = user_data;
g_hash_table_remove(sub_hash, key);
g_hash_table_remove(subscription_global, key);
return;
}
static void free_event_resource(gpointer key,
gpointer value, gpointer user_data)
{
SaEvtEventHandleT event_handle;
evt_event_handle *event_hd;
GHashTable *event_handle_hash;
event_handle = (SaEvtEventHandleT)key;
event_hd = (evt_event_handle *)value;
event_handle_hash = (GHashTable *)user_data;
free_event(event_hd);
g_hash_table_remove(evt_event_hash, key);
return;
}
static void free_ch_resource(gpointer key,
gpointer value, gpointer user_data)
{
SaEvtChannelHandleT ch_handle;
evt_channel_handle *ch_hd;
GHashTable *ch_hash, *event_handle_hash, *subscription_hash;
ch_handle = (SaEvtChannelHandleT)key;
ch_hd = (evt_channel_handle *)value;
ch_hash = (GHashTable *)user_data;
g_hash_table_remove(evt_channel_hash, (gpointer)ch_handle);
g_hash_table_remove(ch_hash, (gpointer)ch_handle);
event_handle_hash = ch_hd->event_handle_hash;
if(event_handle_hash != NULL){
g_hash_table_foreach(event_handle_hash,
free_event_resource, event_handle_hash);
}
subscription_hash = ch_hd->subscription_hash;
if(subscription_hash != NULL){
g_hash_table_foreach(subscription_hash,
free_subscription_resource, subscription_hash);
}
return;
}
static SaErrorT send_evt_finalize(struct IPC_CHANNEL *ch,
evt_handle *evt_hd)
{
SaSizeT msg_len;
void *msg;
SaUint8T *tmp_char;
msg_len = 1;
msg = g_malloc(msg_len);
if(msg == NULL){
return SA_ERR_NO_MEMORY;
}
tmp_char = (SaUint8T *)msg;
*(tmp_char) = EVT_FINALIZE;
send_to_evt_daemon(ch, msg, msg_len);
return SA_OK;
}
SaErrorT
saEvtFinalize(SaEvtHandleT evtHandle)
{
evt_handle *evt_hd;
struct IPC_CHANNEL *ch;
evt_hd = g_hash_table_lookup(evt_handle_hash, (gpointer)evtHandle);
if( evt_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
/*close the connection */
ch = evt_hd->ch;
send_evt_finalize(ch, evt_hd);
ch->ops->destroy(ch);
/*free up the resources, free the channel, the events */
g_hash_table_remove(evt_handle_hash, (gpointer)evtHandle);
g_hash_table_foreach(evt_hd->evt_channel_hash,
free_ch_resource,
evt_hd->evt_channel_hash);
free_event_queue(evt_hd->event_queue);
g_free(evt_hd);
return SA_OK;
}
static SaErrorT send_channel_close(IPC_Channel *ch,
evt_channel_handle *evt_channel_hd)
{
void *msg;
char *tmp_char;
SaSizeT str_len, msg_len;
str_len = evt_channel_hd->channelName.length;
msg_len = 1+sizeof(SaSizeT)+str_len+sizeof(void *);
msg = g_malloc(msg_len);
if(msg == NULL){
return SA_ERR_NO_MEMORY;
}
tmp_char = msg;
*tmp_char = EVT_CLOSE_EVENT_CHANNEL;
tmp_char++;
memcpy(tmp_char, &str_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
strncpy(tmp_char, evt_channel_hd->channelName.value, str_len);
tmp_char = tmp_char + str_len;
memcpy(tmp_char, &(evt_channel_hd->ch_instance), sizeof(void *));
send_to_evt_daemon(ch, msg, msg_len);
return SA_OK;
}
SaErrorT
saEvtChannelClose(SaEvtChannelHandleT channelHandle)
{
evt_channel_handle *evt_channel_hd;
evt_handle *evt_hd;
GHashTable *event_handle_hash, *subscription_hash;
/*free events, free subscriptions, free item in hash table, free evt_channel_hd */
evt_channel_hd = g_hash_table_lookup(evt_channel_hash,
(gpointer)channelHandle);
if(evt_channel_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
send_channel_close(evt_channel_hd->ch ,evt_channel_hd);
event_handle_hash = evt_channel_hd->event_handle_hash;
if(event_handle_hash != NULL){
g_hash_table_foreach(event_handle_hash,
free_event_resource, event_handle_hash);
g_hash_table_destroy(event_handle_hash);
}
subscription_hash = evt_channel_hd->subscription_hash;
if(subscription_hash != NULL){
g_hash_table_foreach(subscription_hash,
free_subscription_resource, subscription_hash);
g_hash_table_destroy(subscription_hash);
}
evt_hd = g_hash_table_lookup(evt_handle_hash,
(gpointer)evt_channel_hd->evt_handle);
g_hash_table_remove(evt_hd->evt_channel_hash, (gpointer)channelHandle);
g_hash_table_remove(evt_channel_hash, (gpointer)(channelHandle));
g_free(evt_channel_hd);
return SA_OK;
}
SaErrorT
saEvtEventAllocate(const SaEvtChannelHandleT channelHandle,
SaEvtEventHandleT *eventHandle)
{
evt_event_handle *event_hd;
evt_channel_handle *evt_channel_hd;
GHashTable *event_handle_hash;
if(eventHandle == NULL){
return SA_ERR_INVALID_PARAM;
}
evt_channel_hd = g_hash_table_lookup(evt_channel_hash,
(gpointer)channelHandle);
if(evt_channel_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
event_hd = (evt_event_handle *)g_malloc0(sizeof(evt_event_handle));
if (!event_hd)
return SA_ERR_NO_MEMORY;
event_handle_hash = evt_channel_hd->event_handle_hash;
event_hd->channelId = channelHandle;
if(get_handle(&event_handle_database, eventHandle) != SA_OK){
g_free(event_hd);
return SA_ERR_LIBRARY;
}
g_hash_table_insert(evt_event_hash, (gpointer)*eventHandle, event_hd);
g_hash_table_insert(evt_channel_hd->event_handle_hash,
(gpointer)*eventHandle, event_hd);
return SA_OK;
}
SaErrorT
saEvtEventFree(SaEvtEventHandleT eventHandle)
{
evt_event_handle *event_hd;
evt_channel_handle *evt_channel_hd;
event_hd = g_hash_table_lookup(evt_event_hash, (gpointer)eventHandle);
if(event_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
free_event(event_hd);
evt_channel_hd = g_hash_table_lookup(evt_channel_hash,
(gpointer)event_hd->channelId);
if(evt_channel_hd == NULL){
return SA_ERR_LIBRARY;
}
g_hash_table_remove(evt_channel_hd->event_handle_hash,
(gpointer)eventHandle);
g_hash_table_remove(evt_event_hash,
(gpointer)eventHandle);
put_handle(&event_handle_database, eventHandle);
return SA_OK;
}
static SaErrorT copy_patternarray(evt_event_handle *event_hd,
const SaEvtEventPatternArrayT *patternArray)
{
SaSizeT number, i, size=0;
SaEvtEventPatternT *pattern;
SaSizeT *tmp_size;
SaUint8T *tmp_char;
number = patternArray->patternsNumber;
pattern = patternArray->patterns;
/*size = field1(number of patterns)+ field2(length of each pattern)+ field3(patterns) */
for(i=0; i<number; i++){
size = size + (pattern+i)->patternSize;
}
size = size + (number+1)*sizeof(SaSizeT);
event_hd->patternArray = g_malloc(size);
event_hd->event_size = size;
if(event_hd->patternArray == NULL){
return SA_ERR_NO_MEMORY;
}
tmp_size = event_hd->patternArray;
*(tmp_size) = number;
tmp_size++;
for(i=0; i<number; i++){
*(tmp_size) = (pattern+i)->patternSize;
tmp_size++;
}
tmp_char = (SaUint8T *)tmp_size;
for(i=0; i<number; i++){
strncpy(tmp_char, (pattern+i)->pattern,
(pattern+i)->patternSize);
tmp_char = tmp_char + (pattern+i)->patternSize;
}
return SA_OK;
}
SaErrorT
saEvtEventAttributesSet(SaEvtEventHandleT eventHandle,
const SaEvtEventPatternArrayT *patternArray,
SaUint8T priority,
SaTimeT retentionTime,
const SaNameT *publisherName)
{
evt_event_handle *event_hd;
if((patternArray == NULL) || (publisherName == NULL)){
return SA_ERR_INVALID_PARAM;
}
if(priority > SA_EVT_LOWEST_PRIORITY){
return SA_ERR_INVALID_PARAM;
}
event_hd = (evt_event_handle *)g_hash_table_lookup(evt_event_hash,
(gpointer)(eventHandle));
if(event_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
copy_patternarray(event_hd, patternArray);
event_hd->priority = priority;
event_hd->retentionTime = retentionTime;
event_hd->publisherName.length = publisherName->length;
memcpy(event_hd->publisherName.value, publisherName->value,
publisherName->length);
event_hd->publishTime = (SaTimeT)time(NULL);
event_hd->set_flag = 1;
return SA_OK;
}
#define min(A,B) ((A)<(B) ? (A) : (B))
SaErrorT
saEvtEventAttributesGet(const SaEvtEventHandleT eventHandle,
SaEvtEventPatternArrayT *patternArray,
SaUint8T *priority,
SaTimeT *retentionTime,
SaNameT *publisherName,
SaTimeT *publishTime,
SaEvtEventIdT *eventId)
{
evt_event_handle *event_hd;
SaSizeT number, *tmp_size, min_number, i;
SaUint8T *tmp_char;
SaEvtEventPatternT *patterns;
event_hd = (evt_event_handle *)g_hash_table_lookup(
evt_event_hash, (gpointer)eventHandle);
if(event_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
/*TODO: what should be done if patterSize conflicts */
if(patternArray != NULL){
tmp_size = (SaSizeT *)event_hd->patternArray;
number = *(tmp_size);
tmp_size++;
tmp_char = (SaUint8T *)(tmp_size+number);
min_number = min(patternArray->patternsNumber, number);
patternArray->patternsNumber = min_number;
patterns = patternArray->patterns;
for(i=0; i<min_number; i++){
patterns[i].patternSize = min(patterns[i].patternSize,
*(tmp_size));
memcpy(patterns[i].pattern, tmp_char,
patterns[i].patternSize);
tmp_char += *(tmp_size);
tmp_size++;
}
}
if(priority != NULL){
*(priority) = event_hd->priority;
}
if(retentionTime != NULL){
*(retentionTime) = event_hd->retentionTime;
}
if(publisherName != NULL){
publisherName->length = event_hd->publisherName.length;
memcpy(publisherName->value, event_hd->publisherName.value,
publisherName->length);
}
if(publishTime != NULL){
*(publishTime) = event_hd->publishTime;
}
if(eventId != NULL){
*(eventId) = event_hd->eventId;
}
return SA_OK;
}
static SaErrorT send_publish(IPC_Channel *ch,
SaNameT *channel_name,
SaEvtEventHandleT eventHandle,
evt_event_handle *event_hd,
const void *eventData,
SaSizeT eventDataSize)
{
void *msg;
char *tmp_char;
SaSizeT str_len, publisher_len, msg_len;
str_len = channel_name->length;
publisher_len = event_hd->publisherName.length;
msg_len = 1+sizeof(SaSizeT)+str_len+sizeof(SaEvtEventHandleT)+
sizeof(SaUint8T)+sizeof(SaTimeT)+sizeof(SaSizeT)+
publisher_len+sizeof(SaTimeT)+sizeof(SaSizeT)+
event_hd->event_size+sizeof(SaSizeT)+eventDataSize;
msg = g_malloc(msg_len);
if(msg == NULL){
return SA_ERR_NO_MEMORY;
}
tmp_char = (char *)msg;
*(tmp_char) = EVT_PUBLISH;
tmp_char++;
memcpy(tmp_char, &str_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
memcpy(tmp_char, channel_name->value, str_len);
tmp_char += str_len;
memcpy(tmp_char, &eventHandle, sizeof(SaEvtEventHandleT));
tmp_char += sizeof(SaEvtEventHandleT);
memcpy(tmp_char, &(event_hd->priority), sizeof(SaUint8T));
tmp_char += sizeof(SaUint8T);
memcpy(tmp_char, &(event_hd->retentionTime), sizeof(SaTimeT));
tmp_char += sizeof(SaTimeT);
memcpy(tmp_char, &publisher_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
memcpy(tmp_char, event_hd->publisherName.value, publisher_len);
tmp_char += publisher_len;
memcpy(tmp_char, &(event_hd->publishTime), sizeof(SaTimeT));
tmp_char += sizeof(SaTimeT);
memcpy(tmp_char, &(event_hd->event_size), sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
memcpy(tmp_char, event_hd->patternArray, event_hd->event_size);
tmp_char += event_hd->event_size;
memcpy(tmp_char, &eventDataSize, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
memcpy(tmp_char, eventData, eventDataSize);
tmp_char += eventDataSize;
send_to_evt_daemon(ch, msg, msg_len);
return SA_OK;
}
SaErrorT
saEvtEventPublish(const SaEvtEventHandleT eventHandle,
const void *eventData,
SaSizeT eventDataSize,
SaEvtEventIdT *eventId)
{
evt_channel_handle *evt_channel_hd;
evt_event_handle *event_hd;
evt_handle *evt_hd;
struct IPC_CHANNEL *ch;
SaNameT *channel_name;
int fd;
fd_set rset;
struct daemon_msg *msg_reply;
struct open_channel_reply *open_ch_reply;
event_hd = g_hash_table_lookup(evt_event_hash, (gpointer)eventHandle);
if(event_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
if(event_hd->set_flag == 0){
return SA_ERR_INVALID_PARAM;
}
evt_channel_hd = g_hash_table_lookup(evt_channel_hash,
(gpointer)event_hd->channelId);
if(evt_channel_hd == NULL){
return SA_ERR_LIBRARY;
}
evt_hd = g_hash_table_lookup(evt_handle_hash,
(gpointer)(evt_channel_hd->evt_handle));
if(evt_hd == NULL){
return SA_ERR_LIBRARY;
}
ch = evt_channel_hd->ch;
channel_name = &(evt_channel_hd->channelName);
send_publish(ch, channel_name, eventHandle,
event_hd, eventData, eventDataSize);
sleep(1);
fd = evt_channel_hd->selectionObject;
for(;;){
FD_ZERO(&rset);
FD_SET(fd, &rset);
if(select(fd + 1, &rset, NULL,NULL,NULL) == -1){
/*perror("select"); */
return(1);
}
msg_reply = read_from_ipc(ch);
if(msg_reply->msg_type == EVT_PUBLISH_REPLY){
if(eventHandle ==
msg_reply->private.pub_reply->eventHandle){
if(msg_reply->private.pub_reply->ret_code
== SA_OK){
break;
}else{
return msg_reply->private.pub_reply->ret_code;
}
}else{
/*update timeout, continue */
}
}else if(msg_reply->msg_type == EVT_NORMAL_EVENT)
{
/*TODO: update timeout, continue */
event_hd = msg_reply->private.event;
append_to_event_queue(evt_hd->event_queue, event_hd);
}else if(msg_reply->msg_type == EVT_ASYN_CH_OPEN_REPLY_FROM_DAEMON)
{
open_ch_reply = msg_reply->private.open_ch_reply;
append_to_reply_queue(evt_hd->event_queue,
open_ch_reply);
}else
{
/*update timeout, continue */
/*error msg */
}
/*if msg_type is normal event, buffer it and continue */
/*if msg_type is publish_reply, break */
}
*(eventId) = (SaEvtEventIdT)msg_reply->private.pub_reply->event_id;
return SA_OK;
}
SaErrorT
saEvtEventSubscribe(const SaEvtChannelHandleT channelHandle,
const SaEvtEventFilterArrayT *filters,
SaEvtSubscriptionIdT subscriptionId)
{
evt_channel_handle *evt_channel_hd;
struct IPC_CHANNEL *ch;
GHashTable *subscription_hash;
SaUint8T *tmp_char;
SaSizeT msg_size;
SaSizeT str_len, number, i, filter_size=0;
void *msg;
SaEvtEventFilterT *filter;
void *tmp_pointer;
evt_channel_hd = (evt_channel_handle *)g_hash_table_lookup(
evt_channel_hash,
(gpointer)channelHandle);
if(evt_channel_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
if((evt_channel_hd->open_flags & SA_EVT_CHANNEL_SUBSCRIBER)
!= SA_EVT_CHANNEL_SUBSCRIBER){
return SA_ERR_INVALID_PARAM;
}
ch = evt_channel_hd->ch;
subscription_hash = evt_channel_hd->subscription_hash;
tmp_pointer = g_hash_table_lookup(subscription_global,
(gpointer)subscriptionId);
if(tmp_pointer != NULL){
return SA_ERR_EXIST;
}
g_hash_table_insert(subscription_hash,
(gpointer)subscriptionId,
(gpointer)subscriptionId);
g_hash_table_insert(subscription_global,
(gpointer)subscriptionId,
(gpointer)subscriptionId);
/*msg_size= msg_type+ch_name_len+ch_name+channel_id+sub_id+filter_len+filters_number+pattern */
str_len = evt_channel_hd->channelName.length;
/* calculate filter length, then copy it to msg */
number = filters->filtersNumber;
filter = filters->filters;
for(i=0; i<number; i++){
filter_size += filter[i].filter.patternSize;
}
filter_size = sizeof(SaSizeT)+(number*sizeof(SaSizeT))+
(number*sizeof(SaEvtEventFilterTypeT))+filter_size;
msg_size = 1+sizeof(SaSizeT)+str_len+sizeof(void *)+
sizeof(subscriptionId)+sizeof(SaSizeT)+
filter_size+sizeof(SaEvtChannelHandleT);
msg = g_malloc(msg_size);
if(msg == NULL){
return SA_ERR_NO_MEMORY;
}
tmp_char = (SaUint8T *)msg;
*(tmp_char) = EVT_SUBSCRIBE;
tmp_char++;
memcpy(tmp_char, &str_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
memcpy(tmp_char, evt_channel_hd->channelName.value, str_len);
tmp_char += str_len;
memcpy(tmp_char, &(evt_channel_hd->ch_instance), sizeof(void *));
tmp_char += sizeof(void *);
memcpy(tmp_char, &subscriptionId, sizeof(SaEvtSubscriptionIdT));
tmp_char += sizeof(SaEvtSubscriptionIdT);
memcpy(tmp_char, &filter_size, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
memcpy(tmp_char, &number, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
for(i=0; i<number; i++){
memcpy(tmp_char, &(filter[i].filterType), sizeof(SaEvtEventFilterTypeT));
tmp_char += sizeof(SaEvtEventFilterTypeT);
memcpy(tmp_char, &(filter[i].filter.patternSize), sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
memcpy(tmp_char, filter[i].filter.pattern,
filter[i].filter.patternSize);
tmp_char += filter[i].filter.patternSize;
}
memcpy(tmp_char, &channelHandle, sizeof(SaEvtChannelHandleT));
send_to_evt_daemon(ch, msg, msg_size);
return SA_OK;
}
SaErrorT saEvtEventUnsubscribe(
SaEvtChannelHandleT channelHandle,
SaEvtSubscriptionIdT subscriptionId
)
{
evt_channel_handle *evt_channel_hd;
GHashTable *subscription_hash;
SaSizeT msg_size;
SaSizeT str_len;
void *msg;
char *tmp_char;
struct IPC_CHANNEL *ch;
evt_channel_hd = (evt_channel_handle *)g_hash_table_lookup(
evt_channel_hash,
(gpointer)channelHandle);
if(evt_channel_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
ch = evt_channel_hd->ch;
subscription_hash = evt_channel_hd->subscription_hash;
if(g_hash_table_lookup(subscription_hash,(gpointer)subscriptionId)
== NULL){
return SA_ERR_NAME_NOT_FOUND;
}
g_hash_table_remove(subscription_hash, (gpointer)subscriptionId);
/* construct the msg and send to daemon */
str_len = evt_channel_hd->channelName.length;
msg_size = 1+sizeof(SaSizeT)+str_len+sizeof(void *)+
sizeof(SaEvtSubscriptionIdT);
msg = g_malloc(msg_size);
if(msg == NULL){
return SA_ERR_LIBRARY;
}
tmp_char = msg;
*(tmp_char) = EVT_UNSUBSCRIBE;
tmp_char++;
memcpy(tmp_char, &str_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
strncpy(tmp_char, evt_channel_hd->channelName.value, str_len);
tmp_char += str_len;
memcpy(tmp_char, &(evt_channel_hd->ch_instance), sizeof(void *));
tmp_char += sizeof(void *);
memcpy(tmp_char, &subscriptionId, sizeof(SaEvtSubscriptionIdT));
send_to_evt_daemon(ch, msg, msg_size);
return SA_OK;
}
SaErrorT
saEvtSelectionObjectGet(const SaEvtHandleT evtHandle,
SaSelectionObjectT *selectionObject)
{
evt_handle *evt_hd;
if(selectionObject == NULL){
return SA_ERR_INVALID_PARAM;
}
evt_hd = g_hash_table_lookup(evt_handle_hash, (gpointer)evtHandle);
if( evt_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
*selectionObject = evt_hd->selectionObject;
return SA_OK;
}
static void *read_from_event_queue(struct event_queue_s *event_queue,
SaUint8T *type)
{
SaSizeT i;
struct queue_head *queue;
evt_event_handle *event_tmp = NULL;
struct open_channel_reply *reply_tmp = NULL;
void *ret = NULL;
if(event_queue->event_number != 0){
for(i=SA_EVT_HIGHEST_PRIORITY;i<=SA_EVT_LOWEST_PRIORITY;i++){
queue = &(event_queue->queue[i]);
if(queue->head != NULL){
event_tmp = queue->head;
queue->head = queue->head->next;
if(queue->head == NULL){
queue->tail = NULL;
}
event_tmp->next = NULL;
event_queue->event_number--;
*(type) = EVT_NORMAL_EVENT;
ret = (void *)event_tmp;
break;
}else{
continue;
}
}
}else if(event_queue->reply_number != 0){
reply_tmp = event_queue->open_ch_reply_queue.head;
event_queue->open_ch_reply_queue.head =
event_queue->open_ch_reply_queue.head->next;
if(event_queue->open_ch_reply_queue.head == NULL){
event_queue->open_ch_reply_queue.tail = NULL;
}
reply_tmp->next = NULL;
event_queue->reply_number--;
*(type) = EVT_CH_OPEN_REPLY_FROM_DAEMON;
ret = (void *)reply_tmp;
}
return ret;
}
SaErrorT
saEvtDispatch(const SaEvtHandleT evtHandle,
SaDispatchFlagsT dispatchFlags)
{
evt_handle *evt_hd;
struct IPC_CHANNEL *ch;
evt_event_handle *event_hd;
evt_channel_handle *evt_channel_hd;
struct daemon_msg *msg;
SaEvtEventHandleT event_handle;
SaUint8T event_type;
void *tmp_void;
struct open_channel_reply *open_ch_reply;
int fd;
fd_set rset;
struct timeval time_out;
int ret;
evt_hd = (evt_handle *)g_hash_table_lookup(evt_handle_hash,
(gpointer)evtHandle);
if( evt_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
if((dispatchFlags < 1) || (dispatchFlags > 3)){
return SA_ERR_BAD_FLAGS;
}
/*can read two types of message from IPC: */
/*1 EVT_NORMAL_EVENT */
/*2 EVT_CH_OPEN_REPLY_FROM_DAEMON: for channel_open_async */
switch(dispatchFlags){
case SA_DISPATCH_ONE:
tmp_void = read_from_event_queue(evt_hd->event_queue,
&event_type);
if(tmp_void == NULL){
ch = evt_hd->ch;
msg = read_from_ipc(ch);
if(msg == NULL){
ch->ops->destroy(ch);
return SA_ERR_LIBRARY;
}
event_type = msg->msg_type;
tmp_void = (void *)msg->private.event;
}
if(event_type == EVT_NORMAL_EVENT){
event_hd = (evt_event_handle *)tmp_void;
evt_channel_hd = g_hash_table_lookup(
evt_channel_hash,
(gpointer)event_hd->channelId);
if(evt_channel_hd == NULL){
return SA_ERR_LIBRARY;
}
if(get_handle(&event_handle_database,
&event_handle) != SA_OK){
return SA_ERR_LIBRARY;
}
g_hash_table_insert(evt_event_hash,
(gpointer)event_handle,
event_hd);
g_hash_table_insert(
evt_channel_hd->event_handle_hash,
(gpointer)event_handle,
event_hd);
evt_hd->callbacks.saEvtEventDeliverCallback(
event_hd->subscription_id,
event_handle,
event_hd->eventDataSize);
}else if(event_type ==
EVT_ASYN_CH_OPEN_REPLY_FROM_DAEMON){
open_ch_reply = (struct open_channel_reply *)
tmp_void;
evt_channel_hd = g_hash_table_lookup(
evt_channel_hash,
(gpointer)open_ch_reply->clt_ch_handle);
if(evt_channel_hd == NULL){
/*TODO: free open_ch_reply */
return SA_ERR_LIBRARY;
}
evt_channel_hd->ch_instance =
open_ch_reply->ch_instance;
evt_hd->callbacks.saEvtChannelOpenCallback(
evt_channel_hd->invocation,
open_ch_reply->clt_ch_handle,
open_ch_reply->ret_code);
}
break;
case SA_DISPATCH_ALL:
fd = evt_hd->selectionObject;
time_out.tv_sec = 0;
for(;;){
tmp_void = read_from_event_queue(
evt_hd->event_queue,
&event_type);
if(tmp_void == NULL){
FD_ZERO(&rset);
FD_SET(fd, &rset);
ret = select(fd + 1, &rset,NULL,NULL,
&time_out);
if( ret == -1){
/*error */
return SA_ERR_LIBRARY;
}else if(ret == 0){
return SA_OK;
}
ch = evt_hd->ch;
msg = read_from_ipc(ch);
if(msg == NULL){
ch->ops->destroy(ch);
return SA_ERR_LIBRARY;
}
event_type = msg->msg_type;
tmp_void = (void *)msg->private.event;
}
if(event_type == EVT_NORMAL_EVENT){
event_hd = (evt_event_handle *)
tmp_void;
evt_channel_hd = g_hash_table_lookup(
evt_channel_hash,
(gpointer)event_hd->channelId);
if(evt_channel_hd == NULL){
return SA_ERR_LIBRARY;
}
if(get_handle(&event_handle_database,
&event_handle) != SA_OK){
return SA_ERR_LIBRARY;
}
g_hash_table_insert(evt_event_hash,
(gpointer)event_handle,
event_hd);
g_hash_table_insert(
evt_channel_hd->event_handle_hash,
(gpointer)event_handle,
event_hd);
evt_hd->callbacks.
saEvtEventDeliverCallback(
event_hd->subscription_id,
event_handle,
event_hd->eventDataSize);
}else if(event_type ==
EVT_ASYN_CH_OPEN_REPLY_FROM_DAEMON){
open_ch_reply =
(struct open_channel_reply *)
tmp_void;
evt_channel_hd = g_hash_table_lookup(
evt_channel_hash,
(gpointer)open_ch_reply->clt_ch_handle);
if(evt_channel_hd == NULL){
/*TODO: free open_ch_reply */
return SA_ERR_LIBRARY;
}
evt_channel_hd->ch_instance =
open_ch_reply->ch_instance;
evt_hd->callbacks.
saEvtChannelOpenCallback(
evt_channel_hd->invocation,
open_ch_reply->clt_ch_handle,
open_ch_reply->ret_code);
}
}
break;
case SA_DISPATCH_BLOCKING:
break;
}
return SA_OK;
}
SaErrorT
saEvtEventDataGet(SaEvtEventHandleT eventHandle,
void *eventData,
SaSizeT *eventDataSize)
{
evt_event_handle *event_hd;
SaSizeT data_size;
event_hd = (evt_event_handle *)g_hash_table_lookup(evt_event_hash,
(gpointer)(eventHandle));
if(event_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
data_size = (event_hd->eventDataSize > *eventDataSize)
? *eventDataSize : event_hd->eventDataSize;
*eventDataSize = data_size;
memcpy(eventData, event_hd->eventData, data_size);
return SA_OK;
}
SaErrorT saEvtChannelUnlink(SaEvtHandleT evtHandle,
const SaNameT *channelName)
{
void *msg;
char *tmp_char;
SaSizeT str_len, msg_len;
evt_handle *evt_hd;
evt_hd = (evt_handle *)g_hash_table_lookup(evt_handle_hash,
(gpointer)(long)evtHandle);
if(evt_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
str_len = channelName->length;
msg_len = sizeof(char)+sizeof(SaSizeT)+str_len;
msg = g_malloc(msg_len);
if(msg == NULL){
return SA_ERR_NO_MEMORY;
}
tmp_char = (char *)msg;
*(tmp_char) = EVT_CHANNEL_UNLINK;
tmp_char++;
memcpy(tmp_char, &str_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
strncpy(tmp_char, channelName->value, str_len);
send_to_evt_daemon(evt_hd->ch, msg, msg_len);
return SA_OK;
}
SaErrorT saEvtEventRetentionTimeClear(
SaEvtChannelHandleT channelHandle,
const SaEvtEventIdT eventId
)
{
evt_channel_handle *evt_channel_hd;
SaSizeT str_len, msg_size;
void *msg;
char *tmp_char;
struct IPC_CHANNEL *ch;
int fd;
fd_set rset;
struct daemon_msg *msg_reply;
struct clear_retention_time_reply *clear_reply;
evt_event_handle *event_hd;
struct open_channel_reply *open_ch_reply;
evt_handle *evt_hd;
evt_channel_hd = (evt_channel_handle *)g_hash_table_lookup(
evt_channel_hash,
(gpointer)(long)channelHandle);
if(evt_channel_hd == NULL){
return SA_ERR_BAD_HANDLE;
}
evt_hd = (evt_handle *)g_hash_table_lookup(evt_handle_hash,
(gpointer)(long)(evt_channel_hd->evt_handle));
if(evt_hd == NULL){
return SA_ERR_LIBRARY;
}
/*msg_size=1+sizeof(SaSizeT)+str_len+sizeof(SaEvtEventIdT) */
str_len = evt_channel_hd->channelName.length;
msg_size = 1+sizeof(SaSizeT)+str_len+sizeof(SaEvtEventIdT);
msg = g_malloc(msg_size);
tmp_char = (char *)msg;
*(tmp_char) = EVT_CLEAR_RETENTION_TIME;
tmp_char++;
memcpy(tmp_char, &str_len, sizeof(SaSizeT));
tmp_char += sizeof(SaSizeT);
strncpy(tmp_char, evt_channel_hd->channelName.value, str_len);
tmp_char += str_len;
memcpy(tmp_char, &eventId, sizeof(SaEvtEventIdT));
send_to_evt_daemon(evt_channel_hd->ch, msg, msg_size);
/*select wait until receiving the reply */
ch = evt_channel_hd->ch;
fd = evt_channel_hd->selectionObject;
for(;;){
FD_ZERO(&rset);
FD_SET(fd, &rset);
if(select(fd + 1, &rset, NULL,NULL,NULL) == -1){
/*perror("select"); */
return SA_ERR_LIBRARY;
}
msg_reply = read_from_ipc(ch);
if(msg_reply->msg_type == EVT_CLEAR_RETENTION_TIME_REPLY){
clear_reply = msg_reply->private.clear_retention_reply;
if(clear_reply->event_id == eventId){
return clear_reply->ret_code;
}else{
/*error */
/*continue to wait reply from daemon */
continue;
}
}else if(msg_reply->msg_type == EVT_NORMAL_EVENT){
event_hd = msg_reply->private.event;
append_to_event_queue(evt_hd->event_queue, event_hd);
}else if(msg_reply->msg_type == EVT_ASYN_CH_OPEN_REPLY_FROM_DAEMON){
open_ch_reply = msg_reply->private.open_ch_reply;
append_to_reply_queue(evt_hd->event_queue,
open_ch_reply);
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1