Просмотр исходного кода

Add unlink function.

(Logical change 1.137)


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@493 fd59a12c-fef9-0310-b244-a6a79926bd2f
Mark Haverkamp 21 лет назад
Родитель
Сommit
191871bb73
4 измененных файлов с 1046 добавлено и 236 удалено
  1. 357 58
      exec/evt.c
  2. 62 10
      include/ipc_evt.h
  3. 220 168
      lib/evt.c
  4. 407 0
      test/testevt.c

+ 357 - 58
exec/evt.c

@@ -35,6 +35,7 @@
 #define RECOVERY_DEBUG LOG_LEVEL_DEBUG
 #define RECOVERY_DEBUG LOG_LEVEL_DEBUG
 #define CHAN_DEL_DEBUG LOG_LEVEL_DEBUG
 #define CHAN_DEL_DEBUG LOG_LEVEL_DEBUG
 #define CHAN_OPEN_DEBUG LOG_LEVEL_DEBUG
 #define CHAN_OPEN_DEBUG LOG_LEVEL_DEBUG
+#define CHAN_UNLINK_DEBUG LOG_LEVEL_DEBUG
 #define REMOTE_OP_DEBUG LOG_LEVEL_DEBUG
 #define REMOTE_OP_DEBUG LOG_LEVEL_DEBUG
 
 
 #include <sys/types.h>
 #include <sys/types.h>
@@ -68,6 +69,7 @@ static int lib_evt_open_channel(struct conn_info *conn_info, void *message);
 static int lib_evt_open_channel_async(struct conn_info *conn_info, 
 static int lib_evt_open_channel_async(struct conn_info *conn_info, 
 		void *message);
 		void *message);
 static int lib_evt_close_channel(struct conn_info *conn_info, void *message);
 static int lib_evt_close_channel(struct conn_info *conn_info, void *message);
+static int lib_evt_unlink_channel(struct conn_info *conn_info, void *message);
 static int lib_evt_event_subscribe(struct conn_info *conn_info, 
 static int lib_evt_event_subscribe(struct conn_info *conn_info, 
 		void *message);
 		void *message);
 static int lib_evt_event_unsubscribe(struct conn_info *conn_info, 
 static int lib_evt_event_unsubscribe(struct conn_info *conn_info, 
@@ -113,6 +115,11 @@ static struct libais_handler evt_libais_handlers[] = {
 	.response_id = 			MESSAGE_RES_EVT_CLOSE_CHANNEL,
 	.response_id = 			MESSAGE_RES_EVT_CLOSE_CHANNEL,
 	},
 	},
 	{
 	{
+	.libais_handler_fn = 	lib_evt_unlink_channel,
+	.response_size = 		sizeof(struct res_evt_channel_unlink),
+	.response_id = 			MESSAGE_RES_EVT_UNLINK_CHANNEL,
+	},
+	{
 	.libais_handler_fn = 	lib_evt_event_subscribe,
 	.libais_handler_fn = 	lib_evt_event_subscribe,
 	.response_size = 		sizeof(struct res_evt_event_subscribe),
 	.response_size = 		sizeof(struct res_evt_event_subscribe),
 	.response_id = 			MESSAGE_RES_EVT_SUBSCRIBE,
 	.response_id = 			MESSAGE_RES_EVT_SUBSCRIBE,
@@ -168,7 +175,7 @@ struct service_handler evt_service_handler = {
 	.exec_dump_fn				= 0
 	.exec_dump_fn				= 0
 };
 };
 
 
-// TODOstatic totempg_recovery_plug_handle evt_recovery_plug_handle;
+// TODO static totempg_recovery_plug_handle evt_recovery_plug_handle;
 
 
 /* 
 /* 
  * list of all retained events 
  * list of all retained events 
@@ -182,12 +189,49 @@ static DECLARE_LIST_INIT(retained_list);
  */
  */
 static DECLARE_LIST_INIT(esc_head);
 static DECLARE_LIST_INIT(esc_head);
 
 
+/*
+ * list of all unlinked event channel information
+ * 		struct event_svr_channel_instance
+ */
+static DECLARE_LIST_INIT(esc_unlinked_head);
+
 /* 
 /* 
  * list of all active event conn_info structs.
  * list of all active event conn_info structs.
  * 		struct conn_info
  * 		struct conn_info
  */
  */
 static DECLARE_LIST_INIT(ci_head);
 static DECLARE_LIST_INIT(ci_head);
 
 
+
+/*
+ * Global varaibles used by the event service
+ *
+ * base_id_top:		upper bits of next event ID to assign
+ * base_id:			Lower bits of Next event ID to assign
+ * my_node_id:		My cluster node id
+ * in_cfg_change:	Config change occurred.  Figure out who sends retained evts.
+ * 					cleared when retained events have been delivered.
+ * total_members:	how many members in this cluster
+ * checked_in:		keep track during config change.
+ * any_joined:		did any nodes join on this change?
+ * recovery_node:	True if we're the recovery node.
+ * tok_call_handle:	totempg token callback handle for recovery.
+ * next_retained:	pointer to next retained message to send during recovery.
+ * next_chan:		pointer to next channel to send during recovery.
+ *
+ */
+#define BASE_ID_MASK 0xffffffffLL
+static SaEvtEventIdT base_id = 0;
+static SaEvtEventIdT base_id_top = 0;
+static SaClmNodeIdT  my_node_id = 0;
+static int			 in_cfg_change = 0;
+static int			 total_members = 0;
+static int 			 checked_in = 0;
+static int			 any_joined = 0;
+static int			 recovery_node = 0;
+static void 		 *tok_call_handle = 0;
+static struct list_head *next_retained = 0;
+static struct list_head *next_chan = 0;
+
 /*
 /*
  * Structure to track pending channel open requests.
  * Structure to track pending channel open requests.
  * 	ocp_async:			1 for async open
  * 	ocp_async:			1 for async open
@@ -208,13 +252,43 @@ struct open_chan_pending {
 	uint32_t			ocp_c_handle;
 	uint32_t			ocp_c_handle;
 	struct list_head	ocp_entry;
 	struct list_head	ocp_entry;
 };
 };
-	
+
 /*
 /*
  * list of pending channel opens
  * list of pending channel opens
  */
  */
 static DECLARE_LIST_INIT(open_pending);
 static DECLARE_LIST_INIT(open_pending);
 static void chan_open_timeout(void *data);
 static void chan_open_timeout(void *data);
 
 
+/*
+ * Structure to track pending channel unlink requests.
+ * ucp_unlink_id:		unlink ID of unlinked channel.
+ * ucp_conn_info:		conn_info for returning to the library.
+ * ucp_entry:			list entry for pending unlink list.
+ */
+struct unlink_chan_pending {
+	uint64_t	 		ucp_unlink_id;
+	struct conn_info	*ucp_conn_info;
+ 	struct list_head 	ucp_entry;
+};
+
+/*
+ * list of pending unlink requests
+ */
+static DECLARE_LIST_INIT(unlink_pending);
+
+/*
+ * Next unlink ID
+ */
+static uint64_t	base_unlink_id = 0;
+inline uint64_t
+next_chan_unlink_id()
+{
+	uint64_t uid = my_node_id;
+	uid = (uid << 32ULL) | base_unlink_id;
+	base_unlink_id = (base_unlink_id + 1ULL) & BASE_ID_MASK;
+	return uid;
+}
+
 #define min(a,b) ((a) < (b) ? (a) : (b))
 #define min(a,b) ((a) < (b) ? (a) : (b))
 
 
 /*
 /*
@@ -274,6 +348,10 @@ struct open_count {
  * esc_open_chans:		list of opens of this channel.
  * esc_open_chans:		list of opens of this channel.
  * 						(event_svr_channel_open.eco_entry)
  * 						(event_svr_channel_open.eco_entry)
  * esc_entry:			links to other channels. (used by esc_head)
  * esc_entry:			links to other channels. (used by esc_head)
+ * esc_unlink_id:		If non-zero, then the channel has been marked
+ * 						for unlink.  This unlink ID is used to
+ * 						mark events still associated with current openings
+ * 						so they get delivered to the proper recipients.
  */
  */
 struct event_svr_channel_instance {
 struct event_svr_channel_instance {
 	SaNameT				esc_channel_name;
 	SaNameT				esc_channel_name;
@@ -284,6 +362,7 @@ struct event_svr_channel_instance {
 	uint32_t			esc_retained_count;
 	uint32_t			esc_retained_count;
 	struct list_head 	esc_open_chans;
 	struct list_head 	esc_open_chans;
 	struct list_head 	esc_entry;
 	struct list_head 	esc_entry;
+	uint64_t			esc_unlink_id;
 };
 };
 
 
 /*
 /*
@@ -390,37 +469,6 @@ struct member_node_data {
 	struct list_head	mn_entry;
 	struct list_head	mn_entry;
 };
 };
 DECLARE_LIST_INIT(mnd);
 DECLARE_LIST_INIT(mnd);
-
-/*
- * Global varaibles used by the event service
- *
- * base_id_top:		upper bits of next event ID to assign
- * base_id:			Lower bits of Next event ID to assign
- * my_node_id:		My cluster node id
- * in_cfg_change:	Config change occurred.  Figure out who sends retained evts.
- * 					cleared when retained events have been delivered.
- * total_members:	how many members in this cluster
- * checked_in:		keep track during config change.
- * any_joined:		did any nodes join on this change?
- * recovery_node:	True if we're the recovery node.
- * tok_call_handle:	totempg token callback handle for recovery.
- * next_retained:	pointer to next retained message to send during recovery.
- * next_chan:		pointer to next channel to send during recovery.
- *
- */
-#define BASE_ID_MASK 0xffffffffLL
-static SaEvtEventIdT base_id = 0;
-static SaEvtEventIdT base_id_top = 0;
-static SaClmNodeIdT  my_node_id = 0;
-static int			 in_cfg_change = 0;
-static int			 total_members = 0;
-static int 			 checked_in = 0;
-static int			 any_joined = 0;
-static int			 recovery_node = 0;
-static void 		 *tok_call_handle = 0;
-static struct list_head *next_retained = 0;
-static struct list_head *next_chan = 0;
-
 /*
 /*
  * Take the filters we received from the application via the library and 
  * Take the filters we received from the application via the library and 
  * make them into a real SaEvtEventFilterArrayT
  * make them into a real SaEvtEventFilterArrayT
@@ -495,22 +543,56 @@ static void free_filters(SaEvtEventFilterArrayT *fp)
  * Look up a channel in the global channel list
  * Look up a channel in the global channel list
  */
  */
 static struct event_svr_channel_instance *
 static struct event_svr_channel_instance *
-find_channel(SaNameT *chan_name)
+find_channel(SaNameT *chan_name, uint64_t unlink_id)
 {
 {
-	struct list_head *l;
+	struct list_head *l, *head;
 	struct event_svr_channel_instance *eci;
 	struct event_svr_channel_instance *eci;
 
 
-	for (l = esc_head.next; l != &esc_head; l = l->next) {
+	/*
+	 * choose which list to look through
+	 */
+	if (unlink_id == EVT_CHAN_ACTIVE) {
+		head = &esc_head;
+	} else {
+		head = &esc_unlinked_head;
+	}
+
+	for (l = head->next; l != head; l = l->next) {
 
 
 		eci = list_entry(l, struct event_svr_channel_instance, esc_entry);
 		eci = list_entry(l, struct event_svr_channel_instance, esc_entry);
 		if (!name_match(chan_name, &eci->esc_channel_name)) {
 		if (!name_match(chan_name, &eci->esc_channel_name)) {
 			continue;
 			continue;
+		} else if (unlink_id != eci->esc_unlink_id) {
+			continue;
 		}
 		}
 		return eci;
 		return eci;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * Find the last unlinked version of a channel.
+ */
+static struct event_svr_channel_instance *
+find_last_unlinked_channel(SaNameT *chan_name)
+{
+	struct list_head *l;
+	struct event_svr_channel_instance *eci;
+
+	/*
+	 * unlinked channels are added to the head of the list
+	 * so the first one we see is the last one added.
+	 */
+	for (l = esc_unlinked_head.next; l != &esc_unlinked_head; l = l->next) {
+
+		eci = list_entry(l, struct event_svr_channel_instance, esc_entry);
+		if (!name_match(chan_name, &eci->esc_channel_name)) {
+			continue;
+		} 
+	}
+	return 0;
+}
+
 /*
 /*
  * Create and initialize a channel instance structure
  * Create and initialize a channel instance structure
  */
  */
@@ -731,12 +813,15 @@ static void delete_channel(struct event_svr_channel_instance *eci)
 			eci->esc_retained_count);
 			eci->esc_retained_count);
 	/*
 	/*
 	 * If no one has the channel open anywhere and there are no unexpired
 	 * If no one has the channel open anywhere and there are no unexpired
-	 * retained events for this channel, then it is OK to delete the
-	 * data structure.
+	 * retained events for this channel, and it has been marked for deletion
+	 * by an unlink, then it is OK to delete the data structure.
 	 */
 	 */
-	if ((eci->esc_retained_count == 0)  && (eci->esc_total_opens == 0)) {
+	if ((eci->esc_retained_count == 0)  && (eci->esc_total_opens == 0) &&
+			(eci->esc_unlink_id != EVT_CHAN_ACTIVE)) {
 		log_printf(CHAN_DEL_DEBUG, "Delete channel %s\n",
 		log_printf(CHAN_DEL_DEBUG, "Delete channel %s\n",
 			eci->esc_channel_name.value);
 			eci->esc_channel_name.value);
+		log_printf(CHAN_UNLINK_DEBUG, "Delete channel %s, unlink_id %0llx\n",
+			eci->esc_channel_name.value, eci->esc_unlink_id);
 
 
 		if (!list_empty(&eci->esc_open_chans)) {
 		if (!list_empty(&eci->esc_open_chans)) {
 				log_printf(LOG_LEVEL_NOTICE, 
 				log_printf(LOG_LEVEL_NOTICE, 
@@ -761,6 +846,47 @@ static void delete_channel(struct event_svr_channel_instance *eci)
 	}
 	}
 }
 }
 
 
+/*
+ * Mark a channel for deletion.
+ */
+static void unlink_channel(struct event_svr_channel_instance *eci, 
+		uint64_t unlink_id)
+{
+	struct event_data *edp;
+	struct list_head *l;
+
+	log_printf(CHAN_UNLINK_DEBUG, "Unlink request: %s, id 0x%llx\n",
+			eci->esc_channel_name.value, unlink_id);
+	/*
+	 * The unlink ID is used to note that the channel has been marked 
+	 * for deletion and is a way to distinguish between multiple 
+	 * channels of the same name each marked for deletion.
+	 */
+	eci->esc_unlink_id = unlink_id;
+
+	/*
+	 * Move the unlinked channel to the unlinked list.  This way 
+	 * we don't have to worry about filtering it out when we need to
+	 * distribute retained events at recovery time.
+	 */
+	list_del(&eci->esc_entry);
+	list_add(&eci->esc_entry, &esc_unlinked_head);
+
+	/*
+	 * Scan the retained event list and tag any associated with this channel
+	 * with the unlink ID so that they get routed properly.
+	 */
+	for (l = retained_list.next; l != &retained_list; l = l->next) {
+		edp = list_entry(l, struct event_data, ed_retained);
+		if ((edp->ed_my_chan == eci) && 
+				(edp->ed_event.led_chan_unlink_id == EVT_CHAN_ACTIVE)) {
+			edp->ed_event.led_chan_unlink_id = unlink_id;
+		}
+	}
+
+	delete_channel(eci);
+}
+
 /*
 /*
  * Remove the specified node from the node list in this channel.
  * Remove the specified node from the node list in this channel.
  */
  */
@@ -821,7 +947,7 @@ static SaErrorT evt_open_channel(SaNameT *cn, SaUint8T flgs)
 
 
 	ret = SA_AIS_OK;
 	ret = SA_AIS_OK;
 
 
-	eci = find_channel(cn);
+	eci = find_channel(cn, EVT_CHAN_ACTIVE);
 
 
 	/*
 	/*
 	 * If the create flag set, and it doesn't exist, we can make the channel.  
 	 * If the create flag set, and it doesn't exist, we can make the channel.  
@@ -860,7 +986,7 @@ chan_open_end:
 /*
 /*
  * Send a request to close a channel with the rest of the cluster.
  * Send a request to close a channel with the rest of the cluster.
  */
  */
-static SaErrorT evt_close_channel(SaNameT *cn)
+static SaErrorT evt_close_channel(SaNameT *cn, uint64_t unlink_id)
 {
 {
 	struct req_evt_chan_command cpkt;
 	struct req_evt_chan_command cpkt;
 	struct iovec chn_iovec;
 	struct iovec chn_iovec;
@@ -877,7 +1003,8 @@ static SaErrorT evt_close_channel(SaNameT *cn)
 	cpkt.chc_head.id = MESSAGE_REQ_EXEC_EVT_CHANCMD;
 	cpkt.chc_head.id = MESSAGE_REQ_EXEC_EVT_CHANCMD;
 	cpkt.chc_head.size = sizeof(cpkt);
 	cpkt.chc_head.size = sizeof(cpkt);
 	cpkt.chc_op = EVT_CLOSE_CHAN_OP;
 	cpkt.chc_op = EVT_CLOSE_CHAN_OP;
-	cpkt.u.chc_chan = *cn;
+	cpkt.u.chcu.chcu_name = *cn;
+	cpkt.u.chcu.chcu_unlink_id = unlink_id;
 	chn_iovec.iov_base = &cpkt;
 	chn_iovec.iov_base = &cpkt;
 	chn_iovec.iov_len = cpkt.chc_head.size;
 	chn_iovec.iov_len = cpkt.chc_head.size;
 	res = totempg_mcast (&chn_iovec, 1, TOTEMPG_AGREED);
 	res = totempg_mcast (&chn_iovec, 1, TOTEMPG_AGREED);
@@ -1312,7 +1439,7 @@ event_retention_timeout(void *data)
 	list_del(&edp->ed_retained);
 	list_del(&edp->ed_retained);
 	list_init(&edp->ed_retained);
 	list_init(&edp->ed_retained);
 	/*
 	/*
-	 * Check to see it the channel isn't in use anymore.
+	 * Check to see if the channel isn't in use anymore.
 	 */
 	 */
 	edp->ed_my_chan->esc_retained_count--;
 	edp->ed_my_chan->esc_retained_count--;
 	if (edp->ed_my_chan->esc_retained_count == 0) {
 	if (edp->ed_my_chan->esc_retained_count == 0) {
@@ -1335,7 +1462,7 @@ clear_retention_time(SaEvtEventIdT event_id)
 	int ret;
 	int ret;
 
 
 	log_printf(LOG_LEVEL_DEBUG, "Search for Event ID %llx\n", event_id);
 	log_printf(LOG_LEVEL_DEBUG, "Search for Event ID %llx\n", event_id);
-	for(l = retained_list.next; l != &retained_list; l = nxt) {
+	for (l = retained_list.next; l != &retained_list; l = nxt) {
 		nxt = l->next;
 		nxt = l->next;
 		edp = list_entry(l, struct event_data, ed_retained);
 		edp = list_entry(l, struct event_data, ed_retained);
 		if (edp->ed_event.led_event_id != event_id) {
 		if (edp->ed_event.led_event_id != event_id) {
@@ -1788,6 +1915,7 @@ convert_event(struct lib_event_data *evt)
 	 */
 	 */
 
 
 	evt->led_chan_name.length = swab16(evt->led_chan_name.length);
 	evt->led_chan_name.length = swab16(evt->led_chan_name.length);
+	evt->led_chan_unlink_id = swab64(evt->led_chan_unlink_id);
 	evt->led_event_id = swab64(evt->led_event_id);
 	evt->led_event_id = swab64(evt->led_event_id);
 	evt->led_sub_id = swab32(evt->led_sub_id);
 	evt->led_sub_id = swab32(evt->led_sub_id);
 	evt->led_publisher_name.length = swab32(evt->led_publisher_name.length);
 	evt->led_publisher_name.length = swab32(evt->led_publisher_name.length);
@@ -2130,7 +2258,7 @@ common_chan_close(struct event_svr_channel_open	*eco, struct libevt_ci *esip)
 			eco->eco_flags);
 			eco->eco_flags);
 
 
 	/*
 	/*
-	 * Unlink the channel open structure.
+	 * Disconnect the channel open structure.
 	 *
 	 *
 	 * Check for subscriptions and deal with them.  In this case
 	 * Check for subscriptions and deal with them.  In this case
 	 * if there are any, we just implicitly unsubscribe.
 	 * if there are any, we just implicitly unsubscribe.
@@ -2161,7 +2289,8 @@ common_chan_close(struct event_svr_channel_open	*eco, struct libevt_ci *esip)
 	 * of who they have been delivered to.
 	 * of who they have been delivered to.
 	 */
 	 */
 	remove_delivered_channel(eco);
 	remove_delivered_channel(eco);
-	return evt_close_channel(&eco->eco_channel->esc_channel_name);
+	return evt_close_channel(&eco->eco_channel->esc_channel_name,
+			eco->eco_channel->esc_unlink_id);
 }
 }
 
 
 /*
 /*
@@ -2205,6 +2334,72 @@ chan_close_done:
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * Handler for saEvtChannelUnlink
+ */
+static int lib_evt_unlink_channel(struct conn_info *conn_info, void *message)
+{
+	struct req_evt_channel_unlink *req;
+	struct res_evt_channel_unlink res;
+	struct iovec chn_iovec;
+	struct unlink_chan_pending *ucp;
+	struct req_evt_chan_command cpkt;
+	SaAisErrorT error = SA_AIS_ERR_LIBRARY;
+
+	req = message;
+
+	log_printf(CHAN_UNLINK_DEBUG, 
+			"saEvtChannelUnlink (Unlink channel request)\n");
+	log_printf(CHAN_UNLINK_DEBUG, "Channel Name %s\n", 
+			req->iuc_channel_name.value);
+
+	if (!find_channel(&req->iuc_channel_name, EVT_CHAN_ACTIVE)) {
+		log_printf(CHAN_UNLINK_DEBUG, "Channel Name doesn't exist\n");
+		error = SA_AIS_ERR_NOT_EXIST;
+		goto evt_unlink_err;
+	}
+
+	/*
+	 * Set up the data structure so that the channel op
+	 * mcast handler can complete the unlink comamnd back to the 
+	 * requestor.
+	 */
+	ucp = malloc(sizeof(*ucp));
+	if (!ucp) {
+		log_printf(LOG_LEVEL_ERROR,
+				"saEvtChannelUnlink: Memory allocation failure\n");
+		error = SA_AIS_ERR_NO_MEMORY;
+		goto evt_unlink_err;
+	}
+
+	ucp->ucp_unlink_id = next_chan_unlink_id();
+	ucp->ucp_conn_info = conn_info;
+	list_add_tail(&ucp->ucp_entry, &unlink_pending);
+
+	/*
+	 * Put together a mcast packet to notify everyone
+	 * of the channel unlink.
+	 */
+	memset(&cpkt, 0, sizeof(cpkt));
+	cpkt.chc_head.id = MESSAGE_REQ_EXEC_EVT_CHANCMD;
+	cpkt.chc_head.size = sizeof(cpkt);
+	cpkt.chc_op = EVT_UNLINK_CHAN_OP;
+	cpkt.u.chcu.chcu_name = req->iuc_channel_name;
+	cpkt.u.chcu.chcu_unlink_id = ucp->ucp_unlink_id;
+	chn_iovec.iov_base = &cpkt;
+	chn_iovec.iov_len = cpkt.chc_head.size;
+	if (totempg_mcast (&chn_iovec, 1, TOTEMPG_AGREED) == 0) {
+		return 0;
+	}
+
+evt_unlink_err:
+	res.iuc_head.size = sizeof(res);
+	res.iuc_head.id = MESSAGE_RES_EVT_UNLINK_CHANNEL;
+	res.iuc_head.error = error;
+	libais_send_response (conn_info, &res, sizeof(res));
+	return 0;
+}
+
 /*
 /*
  * Subscribe to an event channel.
  * Subscribe to an event channel.
  *
  *
@@ -2449,6 +2644,7 @@ static int lib_evt_event_publish(struct conn_info *conn_info, void *message)
 	req->led_head.id = MESSAGE_REQ_EXEC_EVT_EVENTDATA;
 	req->led_head.id = MESSAGE_REQ_EXEC_EVT_EVENTDATA;
 	req->led_chan_name = eci->esc_channel_name;
 	req->led_chan_name = eci->esc_channel_name;
 	req->led_event_id = event_id;
 	req->led_event_id = event_id;
+	req->led_chan_unlink_id = eci->esc_unlink_id;
 
 
 	/*
 	/*
 	 * Distribute the event.
 	 * Distribute the event.
@@ -2867,13 +3063,30 @@ static int evt_remote_evt(void *msg, struct in_addr source_addr,
 	evtpkt->led_in_addr = source_addr;
 	evtpkt->led_in_addr = source_addr;
 	evtpkt->led_receive_time = clust_time_now();
 	evtpkt->led_receive_time = clust_time_now();
 
 
-	eci = find_channel(&evtpkt->led_chan_name);
+	log_printf(CHAN_UNLINK_DEBUG, 
+				"evt_remote_evt(0): chan %s, id 0x%llx\n",
+					evtpkt->led_chan_name.value, evtpkt->led_chan_unlink_id);
+	eci = find_channel(&evtpkt->led_chan_name, evtpkt->led_chan_unlink_id);
+	/*
+	 * We may have had some events that were already queued when an
+	 * unlink happened, if we don't find the channel in the active list
+	 * look for the last unlinked channel of the same name.  If this channel
+	 * is re-opened the messages will still be routed correctly because new
+	 * active channel messages will be ordered behind the open.
+	 */
+	if (!eci && (evtpkt->led_chan_unlink_id == EVT_CHAN_ACTIVE)) {
+		log_printf(CHAN_UNLINK_DEBUG, 
+				"evt_remote_evt(1): chan %s, id 0x%llx\n",
+					evtpkt->led_chan_name.value, evtpkt->led_chan_unlink_id);
+		eci = find_last_unlinked_channel(&evtpkt->led_chan_name);
+	}
 
 
 	/*
 	/*
-	 * We shouldn't see an event for a channel that we don't know about.
+	 * We shouldn't normally see an event for a channel that we 
+	 * don't know about.
 	 */
 	 */
 	if (!eci) {
 	if (!eci) {
-		log_printf(LOG_LEVEL_WARNING, "Channel %s doesn't exist\n",
+		log_printf(LOG_LEVEL_DEBUG, "Channel %s doesn't exist\n",
 				evtpkt->led_chan_name.value);
 				evtpkt->led_chan_name.value);
 		return 0;
 		return 0;
 	}
 	}
@@ -3018,13 +3231,17 @@ static int evt_remote_recovery_evt(void *msg, struct in_addr source_addr,
 						md->mn_node_info.nodeId, 
 						md->mn_node_info.nodeId, 
 						md->mn_node_info.nodeName.value);
 						md->mn_node_info.nodeName.value);
 
 
-		eci = find_channel(&evtpkt->led_chan_name);
+		log_printf(CHAN_UNLINK_DEBUG, 
+				"evt_recovery_event: chan %s, id 0x%llx\n",
+					evtpkt->led_chan_name.value, evtpkt->led_chan_unlink_id);
+		eci = find_channel(&evtpkt->led_chan_name, evtpkt->led_chan_unlink_id);
 
 
 		/*
 		/*
-		 * We shouldn't see an event for a channel that we don't know about.
+		 * We shouldn't normally see an event for a channel that we don't 
+		 * know about.
 		 */
 		 */
 		if (!eci) {
 		if (!eci) {
-			log_printf(LOG_LEVEL_WARNING, "Channel %s doesn't exist\n",
+			log_printf(LOG_LEVEL_DEBUG, "Channel %s doesn't exist\n",
 				evtpkt->led_chan_name.value);
 				evtpkt->led_chan_name.value);
 			return 0;
 			return 0;
 		}
 		}
@@ -3148,6 +3365,26 @@ open_return:
 	}
 	}
 }
 }
 
 
+/*
+ * Called by the channel unlink exec handler to
+ * respond to the application.
+ */
+static void evt_chan_unlink_finish(struct unlink_chan_pending *ucp)
+{
+	struct res_evt_channel_unlink res;
+
+	log_printf(CHAN_UNLINK_DEBUG, "Unlink channel finish ID 0x%llx\n", 
+											ucp->ucp_unlink_id);
+
+	res.iuc_head.size = sizeof(res);
+	res.iuc_head.id = MESSAGE_RES_EVT_UNLINK_CHANNEL;
+	res.iuc_head.error = SA_AIS_OK;
+	libais_send_response (ucp->ucp_conn_info, &res, sizeof(res));
+
+	list_del(&ucp->ucp_entry);
+	free(ucp);
+}
+
 /*
 /*
  * Take the channel command data and swap the elements so they match 
  * Take the channel command data and swap the elements so they match 
  * our architectures word order.
  * our architectures word order.
@@ -3170,10 +3407,15 @@ convert_chan_packet(struct req_evt_chan_command *cpkt)
 	switch (cpkt->chc_op) {
 	switch (cpkt->chc_op) {
 	
 	
 	case EVT_OPEN_CHAN_OP:
 	case EVT_OPEN_CHAN_OP:
-	case EVT_CLOSE_CHAN_OP:
 		cpkt->u.chc_chan.length = swab16(cpkt->u.chc_chan.length);
 		cpkt->u.chc_chan.length = swab16(cpkt->u.chc_chan.length);
 		break;
 		break;
 
 
+	case EVT_UNLINK_CHAN_OP:
+	case EVT_CLOSE_CHAN_OP:
+		cpkt->u.chcu.chcu_name.length = swab16(cpkt->u.chcu.chcu_name.length);
+		cpkt->u.chcu.chcu_unlink_id = swab64(cpkt->u.chcu.chcu_unlink_id);
+		break;
+
 	case EVT_CLEAR_RET_OP:
 	case EVT_CLEAR_RET_OP:
 		cpkt->u.chc_event_id = swab64(cpkt->u.chc_event_id);
 		cpkt->u.chc_event_id = swab64(cpkt->u.chc_event_id);
 		break;
 		break;
@@ -3259,7 +3501,7 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 
 
 		log_printf(CHAN_OPEN_DEBUG, "Opening channel %s for node 0x%x\n",
 		log_printf(CHAN_OPEN_DEBUG, "Opening channel %s for node 0x%x\n",
 						cpkt->u.chc_chan.value, mn->mn_node_info.nodeId);
 						cpkt->u.chc_chan.value, mn->mn_node_info.nodeId);
-		eci = find_channel(&cpkt->u.chc_chan);
+		eci = find_channel(&cpkt->u.chc_chan, EVT_CHAN_ACTIVE);
 
 
 		if (!eci) {
 		if (!eci) {
 			eci = create_channel(&cpkt->u.chc_chan);
 			eci = create_channel(&cpkt->u.chc_chan);
@@ -3302,12 +3544,12 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 	 */
 	 */
 	case EVT_CLOSE_CHAN_OP:
 	case EVT_CLOSE_CHAN_OP:
 		log_printf(LOG_LEVEL_DEBUG, "Closing channel %s for node 0x%x\n",
 		log_printf(LOG_LEVEL_DEBUG, "Closing channel %s for node 0x%x\n",
-						cpkt->u.chc_chan.value, mn->mn_node_info.nodeId);
-		eci = find_channel(&cpkt->u.chc_chan);
+						cpkt->u.chcu.chcu_name.value, mn->mn_node_info.nodeId);
+		eci = find_channel(&cpkt->u.chcu.chcu_name, cpkt->u.chcu.chcu_unlink_id);
 		if (!eci) {
 		if (!eci) {
 			log_printf(LOG_LEVEL_NOTICE, 
 			log_printf(LOG_LEVEL_NOTICE, 
 					"Channel close request for %s not found\n",
 					"Channel close request for %s not found\n",
-				cpkt->u.chc_chan.value);	
+				cpkt->u.chcu.chcu_name.value);	
 			break;
 			break;
 		}
 		}
 
 
@@ -3323,6 +3565,62 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 		delete_channel(eci);
 		delete_channel(eci);
 		break;
 		break;
 
 
+	/*
+	 * Handle a request for channel unlink saEvtChannelUnlink().  
+	 * We'll look up the channel and mark it as unlinked.  Respond to 
+	 * local library unlink commands.
+	 */
+	case EVT_UNLINK_CHAN_OP: {
+		struct unlink_chan_pending *ucp;
+		struct list_head *l, *nxt;
+
+		log_printf(CHAN_UNLINK_DEBUG, 
+				"Unlink request channel %s unlink ID 0x%llx from node 0x%x\n",
+				cpkt->u.chcu.chcu_name.value,
+				cpkt->u.chcu.chcu_unlink_id,
+				mn->mn_node_info.nodeId);
+
+
+		/*
+		 * look up the channel name and get its assoicated data.
+		 */
+		eci = find_channel(&cpkt->u.chcu.chcu_name, 
+				EVT_CHAN_ACTIVE);
+		if (!eci) {
+			log_printf(LOG_LEVEL_NOTICE, 
+					"Channel unlink request for %s not found\n",
+				cpkt->u.chcu.chcu_name);
+			break;
+		}
+
+		/*
+		 * Mark channel as unlinked.
+		 */
+		unlink_channel(eci, cpkt->u.chcu.chcu_unlink_id);
+
+		/*
+		 * respond only to local library requests.
+		 */
+		if (mn->mn_node_info.nodeId == my_node->nodeId) {
+			/*
+			 * Complete one of our pending unlink requests
+			 */
+			for (l = unlink_pending.next; l != &unlink_pending; l = nxt) {
+				nxt = l->next;
+				ucp = list_entry(l, struct unlink_chan_pending, ucp_entry);
+				log_printf(CHAN_UNLINK_DEBUG, 
+				"Compare channel id 0x%llx 0x%llx\n", 
+					ucp->ucp_unlink_id, eci->esc_unlink_id);
+				if (ucp->ucp_unlink_id == eci->esc_unlink_id) {
+					evt_chan_unlink_finish(ucp);
+					break;
+				}
+			}
+		}
+		break;
+ 	}
+
+
 	/*
 	/*
 	 * saEvtClearRetentiotime handler.
 	 * saEvtClearRetentiotime handler.
 	 */
 	 */
@@ -3375,7 +3673,8 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 				cpkt->u.chc_set_opens.chc_open_count,
 				cpkt->u.chc_set_opens.chc_open_count,
 				mn->mn_node_info.nodeId);
 				mn->mn_node_info.nodeId);
 
 
-		eci = find_channel(&cpkt->u.chc_set_opens.chc_chan_name);
+		eci = find_channel(&cpkt->u.chc_set_opens.chc_chan_name, 
+					EVT_CHAN_ACTIVE);
 		if (!eci) {
 		if (!eci) {
 			eci = create_channel(&cpkt->u.chc_set_opens.chc_chan_name);
 			eci = create_channel(&cpkt->u.chc_set_opens.chc_chan_name);
 		}
 		}

+ 62 - 10
include/ipc_evt.h

@@ -44,6 +44,7 @@ enum req_evt_types {
 	MESSAGE_REQ_EVT_OPEN_CHANNEL = 1,
 	MESSAGE_REQ_EVT_OPEN_CHANNEL = 1,
 	MESSAGE_REQ_EVT_OPEN_CHANNEL_ASYNC,
 	MESSAGE_REQ_EVT_OPEN_CHANNEL_ASYNC,
 	MESSAGE_REQ_EVT_CLOSE_CHANNEL,
 	MESSAGE_REQ_EVT_CLOSE_CHANNEL,
+	MESSAGE_REQ_EVT_UNLINK_CHANNEL,
 	MESSAGE_REQ_EVT_SUBSCRIBE,
 	MESSAGE_REQ_EVT_SUBSCRIBE,
 	MESSAGE_REQ_EVT_UNSUBSCRIBE,
 	MESSAGE_REQ_EVT_UNSUBSCRIBE,
 	MESSAGE_REQ_EVT_PUBLISH,
 	MESSAGE_REQ_EVT_PUBLISH,
@@ -54,6 +55,7 @@ enum req_evt_types {
 enum res_evt_types {
 enum res_evt_types {
 	MESSAGE_RES_EVT_OPEN_CHANNEL = 1,
 	MESSAGE_RES_EVT_OPEN_CHANNEL = 1,
 	MESSAGE_RES_EVT_CLOSE_CHANNEL,
 	MESSAGE_RES_EVT_CLOSE_CHANNEL,
+	MESSAGE_RES_EVT_UNLINK_CHANNEL,
 	MESSAGE_RES_EVT_SUBSCRIBE,
 	MESSAGE_RES_EVT_SUBSCRIBE,
 	MESSAGE_RES_EVT_UNSUBSCRIBE,
 	MESSAGE_RES_EVT_UNSUBSCRIBE,
 	MESSAGE_RES_EVT_PUBLISH,
 	MESSAGE_RES_EVT_PUBLISH,
@@ -143,13 +145,35 @@ struct req_evt_channel_close {
  * MESSAGE_RES_EVT_CLOSE_CHANNEL
  * MESSAGE_RES_EVT_CLOSE_CHANNEL
  *
  *
  * icc_head:		Results head
  * icc_head:		Results head
- * icc_error:		Request result
  *
  *
  */
  */
 struct res_evt_channel_close {
 struct res_evt_channel_close {
 	struct res_header	icc_head;
 	struct res_header	icc_head;
 };
 };
 
 
+/*
+ * MESSAGE_REQ_EVT_UNLINK_CHANNEL
+ *
+ * iuc_head:			Request head
+ * iuc_channel_name:	Name of channel to unlink
+ *
+ */
+struct req_evt_channel_unlink {
+
+	struct req_header		iuc_head;
+	SaNameT					iuc_channel_name;
+};
+
+/*
+ * MESSAGE_RES_EVT_UNLINK_CHANNEL
+ *
+ * iuc_head:		Results head
+ *
+ */
+struct res_evt_channel_unlink {
+	struct res_header	iuc_head;
+};
+
 /* 
 /* 
  * MESSAGE_REQ_EVT_SUBSCRIBE
  * MESSAGE_REQ_EVT_SUBSCRIBE
  *
  *
@@ -233,6 +257,7 @@ struct res_evt_event_data {
  * led_svr_channel_handle:	Server channel handle (1 only)
  * led_svr_channel_handle:	Server channel handle (1 only)
  * led_lib_channel_handle:	Lib channel handle (2 only)
  * led_lib_channel_handle:	Lib channel handle (2 only)
  * led_chan_name:			Channel name (3 and 4 only)
  * led_chan_name:			Channel name (3 and 4 only)
+ * led_chan_unlink_id:		directs delivery to unlinked channels.
  * led_event_id:			Event ID (2, 3 and 4 only)
  * led_event_id:			Event ID (2, 3 and 4 only)
  * led_sub_id:				Subscription ID (2 only)
  * led_sub_id:				Subscription ID (2 only)
  * led_publisher_node_id:	Node ID of event publisher
  * led_publisher_node_id:	Node ID of event publisher
@@ -252,6 +277,7 @@ struct lib_event_data {
 	uint32_t				led_svr_channel_handle;
 	uint32_t				led_svr_channel_handle;
 	SaEvtChannelHandleT		led_lib_channel_handle;
 	SaEvtChannelHandleT		led_lib_channel_handle;
 	SaNameT					led_chan_name;
 	SaNameT					led_chan_name;
+	uint64_t				led_chan_unlink_id;
 	SaEvtEventIdT			led_event_id;
 	SaEvtEventIdT			led_event_id;
 	SaEvtSubscriptionIdT	led_sub_id;
 	SaEvtSubscriptionIdT	led_sub_id;
 	SaClmNodeIdT			led_publisher_node_id;
 	SaClmNodeIdT			led_publisher_node_id;
@@ -312,14 +338,13 @@ struct res_evt_event_clear_retentiontime {
 /*
 /*
  * MESSAGE_REQ_EXEC_EVT_CHANCMD
  * MESSAGE_REQ_EXEC_EVT_CHANCMD
  *
  *
- * chc_header:	Request head
- * chc_chan:	Channel Name
- * chc_op:		Channel operation (open, close, clear retentiontime)
+ * Used for various event related operations.
+ *
  */
  */
-
 enum evt_chan_ops {
 enum evt_chan_ops {
 	EVT_OPEN_CHAN_OP,		/* chc_chan */
 	EVT_OPEN_CHAN_OP,		/* chc_chan */
-	EVT_CLOSE_CHAN_OP,  	/* chc_chan */
+	EVT_CLOSE_CHAN_OP,  	/* chc_close_unlink_chan */
+	EVT_UNLINK_CHAN_OP,  	/* chc_close_unlink_chan */
 	EVT_CLEAR_RET_OP,		/* chc_event_id */
 	EVT_CLEAR_RET_OP,		/* chc_event_id */
 	EVT_SET_ID_OP,			/* chc_set_id */
 	EVT_SET_ID_OP,			/* chc_set_id */
 	EVT_CONF_DONE,			/* no data used */
 	EVT_CONF_DONE,			/* no data used */
@@ -327,24 +352,51 @@ enum evt_chan_ops {
 	EVT_OPEN_COUNT_DONE		/* no data used */
 	EVT_OPEN_COUNT_DONE		/* no data used */
 };
 };
 	
 	
+/*
+ * Used during recovery to set the next issued event ID
+ * based on the highest ID seen by any of the members
+ */
 struct evt_set_id {
 struct evt_set_id {
 	struct in_addr	chc_addr;
 	struct in_addr	chc_addr;
 	SaEvtEventIdT	chc_last_id;
 	SaEvtEventIdT	chc_last_id;
 };
 };
 
 
+/*
+ * For set open count used during recovery to syncronize all nodes
+ *
+ * 	chc_chan_name:		Channel name.
+ * 	chc_open_count:		number of local opens of this channel.
+ */
 struct evt_set_opens {
 struct evt_set_opens {
 	SaNameT		chc_chan_name;
 	SaNameT		chc_chan_name;
 	uint32_t	chc_open_count;
 	uint32_t	chc_open_count;
 };
 };
 
 
+/*
+ * Used to communicate channel to close or unlink.
+ */
+#define EVT_CHAN_ACTIVE 0
+struct evt_close_unlink_chan {
+	SaNameT		chcu_name;
+	uint64_t	chcu_unlink_id;
+};
+
+/*
+ * Sent via MESSAGE_REQ_EXEC_EVT_CHANCMD
+ *
+ * chc_head:	Request head
+ * chc_op:		Channel operation (open, close, clear retentiontime)
+ * u:			union of operation options.
+ */
 struct req_evt_chan_command {
 struct req_evt_chan_command {
 	struct req_header 	chc_head;
 	struct req_header 	chc_head;
 	int 				chc_op;
 	int 				chc_op;
 	union {
 	union {
-		SaNameT				chc_chan;
-		SaEvtEventIdT		chc_event_id;
-		struct evt_set_id	chc_set_id;
-		struct evt_set_opens chc_set_opens;
+		SaNameT					chc_chan;
+		SaEvtEventIdT			chc_event_id;
+		struct evt_set_id		chc_set_id;
+		struct evt_set_opens 	chc_set_opens;
+		struct evt_close_unlink_chan	chcu;
 	} u;
 	} u;
 };
 };
 
 

+ 220 - 168
lib/evt.c

@@ -253,7 +253,7 @@ static void eventHandleInstanceDestructor(void *instance)
 
 
 SaAisErrorT 
 SaAisErrorT 
 saEvtInitialize(
 saEvtInitialize(
-	SaEvtHandleT *evt_handle,
+	SaEvtHandleT *evtHandle,
 	const SaEvtCallbacksT *callbacks,
 	const SaEvtCallbacksT *callbacks,
 	SaVersionT *version)
 	SaVersionT *version)
 {
 {
@@ -273,11 +273,11 @@ saEvtInitialize(
 	 * assign instance data to unique handle
 	 * assign instance data to unique handle
 	 */
 	 */
 	error = saHandleCreate(&evt_instance_handle_db, sizeof(*evti), 
 	error = saHandleCreate(&evt_instance_handle_db, sizeof(*evti), 
-			(void*)evt_handle);
+			(void*)evtHandle);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto error_nofree;
 		goto error_nofree;
 	}
 	}
-	error = saHandleInstanceGet(&evt_instance_handle_db, *evt_handle,
+	error = saHandleInstanceGet(&evt_instance_handle_db, *evtHandle,
 			(void*)&evti);
 			(void*)&evti);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto error_handle_free;
 		goto error_handle_free;
@@ -317,21 +317,21 @@ saEvtInitialize(
 	}
 	}
 
 
 	pthread_mutex_init(&evti->ei_mutex, NULL);
 	pthread_mutex_init(&evti->ei_mutex, NULL);
-	saHandleInstancePut(&evt_instance_handle_db, *evt_handle);
+	saHandleInstancePut(&evt_instance_handle_db, *evtHandle);
 
 
 	return SA_AIS_OK;
 	return SA_AIS_OK;
 
 
 error_handle_put:
 error_handle_put:
-	saHandleInstancePut(&evt_instance_handle_db, *evt_handle);
+	saHandleInstancePut(&evt_instance_handle_db, *evtHandle);
 error_handle_free:
 error_handle_free:
-	(void)saHandleDestroy(&evt_instance_handle_db, *evt_handle);
+	(void)saHandleDestroy(&evt_instance_handle_db, *evtHandle);
 error_nofree:
 error_nofree:
 	return error;
 	return error;
 }
 }
 
 
 /*
 /*
  * The saEvtSelectionObjectGet() function returns the operating system 
  * The saEvtSelectionObjectGet() function returns the operating system 
- * handle selection_object, associated with the handle evt_handle, allowing 
+ * handle selectionObject, associated with the handle evtHandle, allowing 
  * the invoking process to ascertain when callbacks are pending. This 
  * the invoking process to ascertain when callbacks are pending. This 
  * function allows a process to avoid repeated invoking saEvtDispatch() to 
  * function allows a process to avoid repeated invoking saEvtDispatch() to 
  * see if there is a new event, thus, needlessly consuming CPU time. In a 
  * see if there is a new event, thus, needlessly consuming CPU time. In a 
@@ -340,22 +340,22 @@ error_nofree:
  */
  */
 SaAisErrorT
 SaAisErrorT
 saEvtSelectionObjectGet(
 saEvtSelectionObjectGet(
-	SaEvtHandleT evt_handle,
-	SaSelectionObjectT *selection_object)
+	SaEvtHandleT evtHandle,
+	SaSelectionObjectT *selectionObject)
 {
 {
 	struct event_instance *evti;
 	struct event_instance *evti;
 	SaAisErrorT error;
 	SaAisErrorT error;
 
 
-	error = saHandleInstanceGet(&evt_instance_handle_db, evt_handle, 
+	error = saHandleInstanceGet(&evt_instance_handle_db, evtHandle, 
 			(void *)&evti);
 			(void *)&evti);
 
 
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		return error;
 		return error;
 	}
 	}
 
 
-	*selection_object = evti->ei_fd;
+	*selectionObject = evti->ei_fd;
 
 
-	saHandleInstancePut(&evt_instance_handle_db, evt_handle);
+	saHandleInstancePut(&evt_instance_handle_db, evtHandle);
 
 
 	return SA_AIS_OK;
 	return SA_AIS_OK;
 }
 }
@@ -435,12 +435,12 @@ make_evt_done:
 
 
 /*
 /*
  * The saEvtDispatch() function invokes, in the context of the calling 
  * The saEvtDispatch() function invokes, in the context of the calling 
- * thread, one or all of the pending callbacks for the handle evt_handle.
+ * thread, one or all of the pending callbacks for the handle evtHandle.
  */
  */
 SaAisErrorT
 SaAisErrorT
 saEvtDispatch(
 saEvtDispatch(
-	SaEvtHandleT evt_handle,
-	SaDispatchFlagsT dispatch_flags)
+	SaEvtHandleT evtHandle,
+	SaDispatchFlagsT dispatchFlags)
 {
 {
 	struct pollfd ufds;
 	struct pollfd ufds;
 	int timeout = -1;
 	int timeout = -1;
@@ -459,7 +459,7 @@ saEvtDispatch(
 	struct lib_event_data *evt;
 	struct lib_event_data *evt;
 	struct res_evt_event_data res;
 	struct res_evt_event_data res;
 
 
-	error = saHandleInstanceGet(&evt_instance_handle_db, evt_handle,
+	error = saHandleInstanceGet(&evt_instance_handle_db, evtHandle,
 		(void *)&evti);
 		(void *)&evti);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		return error;
 		return error;
@@ -468,7 +468,7 @@ saEvtDispatch(
 	/*
 	/*
 	 * Timeout instantly for SA_DISPATCH_ALL
 	 * Timeout instantly for SA_DISPATCH_ALL
 	 */
 	 */
-	if (dispatch_flags == SA_DISPATCH_ALL) {
+	if (dispatchFlags == SA_DISPATCH_ALL) {
 		timeout = 0;
 		timeout = 0;
 	}
 	}
 
 
@@ -504,7 +504,7 @@ saEvtDispatch(
 		}
 		}
 
 
 		dispatch_avail = (ufds.revents & POLLIN) | (empty == 0);
 		dispatch_avail = (ufds.revents & POLLIN) | (empty == 0);
-		if (dispatch_avail == 0 && dispatch_flags == SA_DISPATCH_ALL) {
+		if (dispatch_avail == 0 && dispatchFlags == SA_DISPATCH_ALL) {
 			pthread_mutex_unlock(&evti->ei_mutex);
 			pthread_mutex_unlock(&evti->ei_mutex);
 			break; /* exit do while cont is 1 loop */
 			break; /* exit do while cont is 1 loop */
 		} else
 		} else
@@ -560,7 +560,7 @@ saEvtDispatch(
 		case MESSAGE_RES_LIB_ACTIVATEPOLL:
 		case MESSAGE_RES_LIB_ACTIVATEPOLL:
 			/*
 			/*
 			 * This is a do nothing message which the node 
 			 * This is a do nothing message which the node 
-			 * executive sends to activate the file evt_handle 
+			 * executive sends to activate the file evtHandle 
 			 * in poll when the library has queued a message into 
 			 * in poll when the library has queued a message into 
 			 * evti->ei_inq. The dispatch is ignored for the 
 			 * evti->ei_inq. The dispatch is ignored for the 
 			 * following two cases:
 			 * following two cases:
@@ -665,7 +665,7 @@ saEvtDispatch(
 		/*
 		/*
 		 * Determine if more messages should be processed
 		 * Determine if more messages should be processed
 		 */
 		 */
-		switch (dispatch_flags) {
+		switch (dispatchFlags) {
 		case SA_DISPATCH_ONE:
 		case SA_DISPATCH_ONE:
 			if (ignore_dispatch) {
 			if (ignore_dispatch) {
 				ignore_dispatch = 0;
 				ignore_dispatch = 0;
@@ -684,14 +684,14 @@ saEvtDispatch(
 	} while (cont);
 	} while (cont);
 
 
 error_unlock:
 error_unlock:
-	saHandleInstancePut(&evt_instance_handle_db, evt_handle);
+	saHandleInstancePut(&evt_instance_handle_db, evtHandle);
 error_nounlock:
 error_nounlock:
 	return error;
 	return error;
 }
 }
 
 
 /*
 /*
  * The saEvtFinalize() function closes the association, represented by the 
  * The saEvtFinalize() function closes the association, represented by the 
- * evt_handle parameter, between the process and the Event Service. It may 
+ * evtHandle parameter, between the process and the Event Service. It may 
  * free up resources. 
  * free up resources. 
  * This function cannot be invoked before the process has invoked the 
  * This function cannot be invoked before the process has invoked the 
  * corresponding saEvtInitialize() function for the Event Service. After 
  * corresponding saEvtInitialize() function for the Event Service. After 
@@ -700,12 +700,12 @@ error_nounlock:
  * reinitialized using the saEvtInitialize() function.
  * reinitialized using the saEvtInitialize() function.
  */
  */
 SaAisErrorT
 SaAisErrorT
-saEvtFinalize(SaEvtHandleT evt_handle)
+saEvtFinalize(SaEvtHandleT evtHandle)
 {
 {
 	struct event_instance *evti;
 	struct event_instance *evti;
 	SaAisErrorT error;
 	SaAisErrorT error;
 
 
-	error = saHandleInstanceGet(&evt_instance_handle_db, evt_handle, 
+	error = saHandleInstanceGet(&evt_instance_handle_db, evtHandle, 
 			(void *)&evti);
 			(void *)&evti);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		return error;
 		return error;
@@ -718,7 +718,7 @@ saEvtFinalize(SaEvtHandleT evt_handle)
 	 */
 	 */
 	if (evti->ei_finalize) {
 	if (evti->ei_finalize) {
 		pthread_mutex_unlock(&evti->ei_mutex);
 		pthread_mutex_unlock(&evti->ei_mutex);
-		saHandleInstancePut(&evt_instance_handle_db, evt_handle);
+		saHandleInstancePut(&evt_instance_handle_db, evtHandle);
 		return SA_AIS_ERR_BAD_HANDLE;
 		return SA_AIS_ERR_BAD_HANDLE;
 	}
 	}
 
 
@@ -728,8 +728,8 @@ saEvtFinalize(SaEvtHandleT evt_handle)
 
 
 	pthread_mutex_unlock(&evti->ei_mutex);
 	pthread_mutex_unlock(&evti->ei_mutex);
 
 
-	saHandleDestroy(&evt_instance_handle_db, evt_handle);
-	saHandleInstancePut(&evt_instance_handle_db, evt_handle);
+	saHandleDestroy(&evt_instance_handle_db, evtHandle);
+	saHandleInstancePut(&evt_instance_handle_db, evtHandle);
 
 
 	return error;
 	return error;
 }
 }
@@ -748,11 +748,11 @@ saEvtFinalize(SaEvtHandleT evt_handle)
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtChannelOpen(
 saEvtChannelOpen(
-	SaEvtHandleT evt_handle, 
-	const SaNameT *channel_name, 
-	SaEvtChannelOpenFlagsT channel_open_flags, 
+	SaEvtHandleT evtHandle, 
+	const SaNameT *channelName, 
+	SaEvtChannelOpenFlagsT channelOpenFlags, 
 	SaTimeT timeout,
 	SaTimeT timeout,
-	SaEvtChannelHandleT *channel_handle)
+	SaEvtChannelHandleT *channelHandle)
 {
 {
 	struct event_instance *evti;
 	struct event_instance *evti;
 	struct req_evt_channel_open req;
 	struct req_evt_channel_open req;
@@ -760,7 +760,7 @@ saEvtChannelOpen(
 	struct event_channel_instance *eci;
 	struct event_channel_instance *eci;
 	SaAisErrorT error;
 	SaAisErrorT error;
 
 
-	error = saHandleInstanceGet(&evt_instance_handle_db, evt_handle,
+	error = saHandleInstanceGet(&evt_instance_handle_db, evtHandle,
 			(void*)&evti);
 			(void*)&evti);
 	
 	
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
@@ -771,15 +771,15 @@ saEvtChannelOpen(
 	 * create a handle for this open channel
 	 * create a handle for this open channel
 	 */
 	 */
 	error = saHandleCreate(&channel_handle_db, sizeof(*eci), 
 	error = saHandleCreate(&channel_handle_db, sizeof(*eci), 
-			(void*)channel_handle);
+			(void*)channelHandle);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto chan_open_put;
 		goto chan_open_put;
 	}
 	}
 
 
-	error = saHandleInstanceGet(&channel_handle_db, *channel_handle,
+	error = saHandleInstanceGet(&channel_handle_db, *channelHandle,
 					(void*)&eci);
 					(void*)&eci);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
-		saHandleDestroy(&channel_handle_db, *channel_handle);
+		saHandleDestroy(&channel_handle_db, *channelHandle);
 		goto chan_open_put;
 		goto chan_open_put;
 	}
 	}
 
 
@@ -789,10 +789,10 @@ saEvtChannelOpen(
 	 */
 	 */
 	req.ico_head.size = sizeof(req);
 	req.ico_head.size = sizeof(req);
 	req.ico_head.id = MESSAGE_REQ_EVT_OPEN_CHANNEL;
 	req.ico_head.id = MESSAGE_REQ_EVT_OPEN_CHANNEL;
-	req.ico_c_handle = *channel_handle;
+	req.ico_c_handle = *channelHandle;
 	req.ico_timeout = timeout;
 	req.ico_timeout = timeout;
-	req.ico_open_flag = channel_open_flags;
-	req.ico_channel_name = *channel_name;
+	req.ico_open_flag = channelOpenFlags;
+	req.ico_channel_name = *channelName;
 
 
 
 
 	pthread_mutex_lock(&evti->ei_mutex);
 	pthread_mutex_lock(&evti->ei_mutex);
@@ -817,35 +817,32 @@ saEvtChannelOpen(
 	}
 	}
 
 
 	eci->eci_svr_channel_handle = res.ico_channel_handle;
 	eci->eci_svr_channel_handle = res.ico_channel_handle;
-	eci->eci_channel_name = *channel_name;
-	eci->eci_open_flags = channel_open_flags;
-	eci->eci_instance_handle = evt_handle;
+	eci->eci_channel_name = *channelName;
+	eci->eci_open_flags = channelOpenFlags;
+	eci->eci_instance_handle = evtHandle;
 	eci->eci_closing = 0;
 	eci->eci_closing = 0;
 	pthread_mutex_init(&eci->eci_mutex, NULL);
 	pthread_mutex_init(&eci->eci_mutex, NULL);
-	saHandleInstancePut (&evt_instance_handle_db, evt_handle);
-	saHandleInstancePut (&channel_handle_db, *channel_handle);
+	saHandleInstancePut (&evt_instance_handle_db, evtHandle);
+	saHandleInstancePut (&channel_handle_db, *channelHandle);
 
 
 	return SA_AIS_OK;
 	return SA_AIS_OK;
 
 
 chan_open_free:
 chan_open_free:
-	saHandleDestroy(&channel_handle_db, *channel_handle);
-	saHandleInstancePut (&channel_handle_db, *channel_handle);
+	saHandleDestroy(&channel_handle_db, *channelHandle);
+	saHandleInstancePut (&channel_handle_db, *channelHandle);
 chan_open_put:
 chan_open_put:
-	saHandleInstancePut (&evt_instance_handle_db, evt_handle);
+	saHandleInstancePut (&evt_instance_handle_db, evtHandle);
 chan_open_done:
 chan_open_done:
 	return error;
 	return error;
 }
 }
 
 
 /*
 /*
  * The saEvtChannelClose() function closes an event channel and frees 
  * The saEvtChannelClose() function closes an event channel and frees 
- * resources allo-cated for that event channel in the invoking process. If 
- * the event channel is not refer-enced by any process and does not hold 
- * any events with non-zero retention time, the Event Service automatically 
- * deletes the event channel from the cluster namespace.
+ * resources allocated for that event channel in the invoking process. 
  */
  */
 
 
 SaAisErrorT 
 SaAisErrorT 
-saEvtChannelClose(SaEvtChannelHandleT channel_handle)
+saEvtChannelClose(SaEvtChannelHandleT channelHandle)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_instance *evti;
 	struct event_instance *evti;
@@ -853,7 +850,7 @@ saEvtChannelClose(SaEvtChannelHandleT channel_handle)
 	struct req_evt_channel_close req;
 	struct req_evt_channel_close req;
 	struct res_evt_channel_close res;
 	struct res_evt_channel_close res;
 
 
-	error = saHandleInstanceGet(&channel_handle_db, channel_handle,
+	error = saHandleInstanceGet(&channel_handle_db, channelHandle,
 			(void*)&eci);
 			(void*)&eci);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto chan_close_done;
 		goto chan_close_done;
@@ -874,7 +871,7 @@ saEvtChannelClose(SaEvtChannelHandleT channel_handle)
 	pthread_mutex_lock(&eci->eci_mutex);
 	pthread_mutex_lock(&eci->eci_mutex);
 	if (eci->eci_closing) {
 	if (eci->eci_closing) {
 		pthread_mutex_unlock(&eci->eci_mutex);
 		pthread_mutex_unlock(&eci->eci_mutex);
-		saHandleInstancePut(&channel_handle_db, channel_handle);
+		saHandleInstancePut(&channel_handle_db, channelHandle);
 		return SA_AIS_ERR_BAD_HANDLE;
 		return SA_AIS_ERR_BAD_HANDLE;
 	}
 	}
 	eci->eci_closing = 1;
 	eci->eci_closing = 1;
@@ -911,8 +908,8 @@ saEvtChannelClose(SaEvtChannelHandleT channel_handle)
 
 
 	saHandleInstancePut(&evt_instance_handle_db, 
 	saHandleInstancePut(&evt_instance_handle_db, 
 					eci->eci_instance_handle);
 					eci->eci_instance_handle);
-	saHandleDestroy(&channel_handle_db, channel_handle);
-	saHandleInstancePut(&channel_handle_db, channel_handle);
+	saHandleDestroy(&channel_handle_db, channelHandle);
+	saHandleInstancePut(&channel_handle_db, channelHandle);
 
 
 	return error;
 	return error;
 
 
@@ -920,7 +917,7 @@ chan_close_put2:
 	saHandleInstancePut(&evt_instance_handle_db, 
 	saHandleInstancePut(&evt_instance_handle_db, 
 					eci->eci_instance_handle);
 					eci->eci_instance_handle);
 chan_close_put1:
 chan_close_put1:
-	saHandleInstancePut(&channel_handle_db, channel_handle);
+	saHandleInstancePut(&channel_handle_db, channelHandle);
 chan_close_done:
 chan_close_done:
 	return error;
 	return error;
 }
 }
@@ -932,10 +929,10 @@ chan_close_done:
  * callback function (SaEvtChannelOpenCallbackT).
  * callback function (SaEvtChannelOpenCallbackT).
  */
  */
 SaAisErrorT
 SaAisErrorT
-saEvtChannelOpenAsync(SaEvtHandleT evt_handle,
+saEvtChannelOpenAsync(SaEvtHandleT evtHandle,
                        SaInvocationT invocation,
                        SaInvocationT invocation,
-                       const SaNameT *channel_name,
-                       SaEvtChannelOpenFlagsT channel_open_flags)
+                       const SaNameT *channelName,
+                       SaEvtChannelOpenFlagsT channelOpenFlags)
 {
 {
 	struct event_instance *evti;
 	struct event_instance *evti;
 	struct req_evt_channel_open req;
 	struct req_evt_channel_open req;
@@ -944,7 +941,7 @@ saEvtChannelOpenAsync(SaEvtHandleT evt_handle,
 	SaEvtChannelHandleT channel_handle;
 	SaEvtChannelHandleT channel_handle;
 	SaAisErrorT error;
 	SaAisErrorT error;
 
 
-	error = saHandleInstanceGet(&evt_instance_handle_db, evt_handle,
+	error = saHandleInstanceGet(&evt_instance_handle_db, evtHandle,
 			(void*)&evti);
 			(void*)&evti);
 	
 	
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
@@ -978,8 +975,8 @@ saEvtChannelOpenAsync(SaEvtHandleT evt_handle,
 	req.ico_c_handle = channel_handle;
 	req.ico_c_handle = channel_handle;
 	req.ico_timeout = 0;
 	req.ico_timeout = 0;
 	req.ico_invocation = invocation;
 	req.ico_invocation = invocation;
-	req.ico_open_flag = channel_open_flags;
-	req.ico_channel_name = *channel_name;
+	req.ico_open_flag = channelOpenFlags;
+	req.ico_channel_name = *channelName;
 
 
 
 
 	pthread_mutex_lock(&evti->ei_mutex);
 	pthread_mutex_lock(&evti->ei_mutex);
@@ -1004,12 +1001,12 @@ saEvtChannelOpenAsync(SaEvtHandleT evt_handle,
 	}
 	}
 
 
 	eci->eci_svr_channel_handle = 0; /* filled in by callback */
 	eci->eci_svr_channel_handle = 0; /* filled in by callback */
-	eci->eci_channel_name = *channel_name;
-	eci->eci_open_flags = channel_open_flags;
-	eci->eci_instance_handle = evt_handle;
+	eci->eci_channel_name = *channelName;
+	eci->eci_open_flags = channelOpenFlags;
+	eci->eci_instance_handle = evtHandle;
 	eci->eci_closing = 0;
 	eci->eci_closing = 0;
 	pthread_mutex_init(&eci->eci_mutex, NULL);
 	pthread_mutex_init(&eci->eci_mutex, NULL);
-	saHandleInstancePut (&evt_instance_handle_db, evt_handle);
+	saHandleInstancePut (&evt_instance_handle_db, evtHandle);
 	saHandleInstancePut (&channel_handle_db, channel_handle);
 	saHandleInstancePut (&channel_handle_db, channel_handle);
 
 
 	return SA_AIS_OK;
 	return SA_AIS_OK;
@@ -1018,20 +1015,75 @@ chan_open_free:
 	saHandleDestroy(&channel_handle_db, channel_handle);
 	saHandleDestroy(&channel_handle_db, channel_handle);
 	saHandleInstancePut (&channel_handle_db, channel_handle);
 	saHandleInstancePut (&channel_handle_db, channel_handle);
 chan_open_put:
 chan_open_put:
-	saHandleInstancePut (&evt_instance_handle_db, evt_handle);
+	saHandleInstancePut (&evt_instance_handle_db, evtHandle);
 chan_open_done:
 chan_open_done:
 	return error;
 	return error;
 }
 }
-
+/*
+ *  The SaEvtChannelUnlink function deletes an existing event channel 
+ *  from the cluster. 
+ *
+ *	After completion of the invocation: 
+ *		- An open of the channel name without a create will fail.
+ *		- The channel remains available to any already opened instances.
+ *		- If an open/create is performed on this channel name a new instance
+ *		  is created.
+ *		- The ulinked channel's resources will be deleted when the last open
+ *		  instance is closed.
+ *		   
+ *		Note that an event channel is only deleted from the cluster 
+ *		namespace when saEvtChannelUnlink() is invoked on it. The deletion 
+ *		of an event channel frees all resources allocated by the Event 
+ *		Service for it, such as published events with non-zero retention 
+ *		time.
+ */
 SaAisErrorT
 SaAisErrorT
-SaEvtChannelUnlink(
+saEvtChannelUnlink(
 	SaEvtHandleT evtHandle,
 	SaEvtHandleT evtHandle,
 	const SaNameT *channelName)
 	const SaNameT *channelName)
 {
 {
-	/* 
-	 * TODO: Fill in code
+	struct event_instance *evti;
+	struct req_evt_channel_unlink req;
+	struct res_evt_channel_unlink res;
+	SaAisErrorT error;
+
+	error = saHandleInstanceGet(&evt_instance_handle_db, evtHandle,
+			(void*)&evti);
+	
+	if (error != SA_AIS_OK) {
+		goto chan_unlink_done;
+	}
+
+	/*
+	 * Send the request to the server and wait for a response
 	 */
 	 */
-	return SA_AIS_ERR_LIBRARY;
+	req.iuc_head.size = sizeof(req);
+	req.iuc_head.id = MESSAGE_REQ_EVT_UNLINK_CHANNEL;
+	req.iuc_channel_name = *channelName;
+
+
+	pthread_mutex_lock(&evti->ei_mutex);
+
+	error = saSendRetry(evti->ei_fd, &req, sizeof(req), MSG_NOSIGNAL);
+	if (error != SA_AIS_OK) {
+		pthread_mutex_unlock (&evti->ei_mutex);
+		goto chan_unlink_put;
+	}
+	error = saRecvQueue(evti->ei_fd, &res, &evti->ei_inq, 
+					MESSAGE_RES_EVT_UNLINK_CHANNEL);
+
+	pthread_mutex_unlock (&evti->ei_mutex);
+
+	if (error != SA_AIS_OK) {
+		goto chan_unlink_put;
+	}
+
+	error = res.iuc_head.error;
+
+chan_unlink_put:
+	saHandleInstancePut (&evt_instance_handle_db, evtHandle);
+chan_unlink_done:
+	return error;
 }
 }
 
 
 /* 
 /* 
@@ -1047,15 +1099,15 @@ SaEvtChannelUnlink(
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventAllocate(
 saEvtEventAllocate(
-	const SaEvtChannelHandleT channel_handle, 
-	SaEvtEventHandleT *event_handle)
+	const SaEvtChannelHandleT channelHandle, 
+	SaEvtEventHandleT *eventHandle)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_data_instance *edi;
 	struct event_data_instance *edi;
 	struct event_instance *evti;
 	struct event_instance *evti;
 	struct event_channel_instance *eci;
 	struct event_channel_instance *eci;
 
 
-	error = saHandleInstanceGet(&channel_handle_db, channel_handle,
+	error = saHandleInstanceGet(&channel_handle_db, channelHandle,
 			(void*)&eci);
 			(void*)&eci);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto alloc_done;
 		goto alloc_done;
@@ -1068,11 +1120,11 @@ saEvtEventAllocate(
 	}
 	}
 
 
 	error = saHandleCreate(&event_handle_db, sizeof(*edi), 
 	error = saHandleCreate(&event_handle_db, sizeof(*edi), 
-			(void*)event_handle);
+			(void*)eventHandle);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto alloc_put2;
 		goto alloc_put2;
 	}
 	}
-	error = saHandleInstanceGet(&event_handle_db, *event_handle,
+	error = saHandleInstanceGet(&event_handle_db, *eventHandle,
 					(void*)&edi);
 					(void*)&edi);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto alloc_put2;
 		goto alloc_put2;
@@ -1082,10 +1134,10 @@ saEvtEventAllocate(
 
 
 	pthread_mutex_init(&edi->edi_mutex, NULL);
 	pthread_mutex_init(&edi->edi_mutex, NULL);
 	edi->edi_freeing = 0;
 	edi->edi_freeing = 0;
-	edi->edi_channel_handle = channel_handle;
+	edi->edi_channel_handle = channelHandle;
 	edi->edi_pub_node = evti->ei_node_id;
 	edi->edi_pub_node = evti->ei_node_id;
 	edi->edi_priority = SA_EVT_LOWEST_PRIORITY;
 	edi->edi_priority = SA_EVT_LOWEST_PRIORITY;
-	saHandleInstancePut (&event_handle_db, *event_handle);
+	saHandleInstancePut (&event_handle_db, *eventHandle);
 
 
 alloc_put2:
 alloc_put2:
 	saHandleInstancePut (&evt_instance_handle_db, eci->eci_instance_handle);
 	saHandleInstancePut (&evt_instance_handle_db, eci->eci_instance_handle);
@@ -1102,12 +1154,12 @@ alloc_done:
  * by saEvtEventAllocate() and by saEvtEventDeliverCallback().
  * by saEvtEventAllocate() and by saEvtEventDeliverCallback().
  */
  */
 SaAisErrorT 
 SaAisErrorT 
-saEvtEventFree(SaEvtEventHandleT event_handle)
+saEvtEventFree(SaEvtEventHandleT eventHandle)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_data_instance *edi;
 	struct event_data_instance *edi;
 
 
-	error = saHandleInstanceGet(&event_handle_db, event_handle,
+	error = saHandleInstanceGet(&event_handle_db, eventHandle,
 			(void*)&edi);
 			(void*)&edi);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto evt_free_done;
 		goto evt_free_done;
@@ -1119,14 +1171,14 @@ saEvtEventFree(SaEvtEventHandleT event_handle)
 	pthread_mutex_lock(&edi->edi_mutex);
 	pthread_mutex_lock(&edi->edi_mutex);
 	if (edi->edi_freeing) {
 	if (edi->edi_freeing) {
 		pthread_mutex_unlock(&edi->edi_mutex);
 		pthread_mutex_unlock(&edi->edi_mutex);
-		saHandleInstancePut(&event_handle_db, event_handle);
+		saHandleInstancePut(&event_handle_db, eventHandle);
 		return SA_AIS_ERR_BAD_HANDLE;
 		return SA_AIS_ERR_BAD_HANDLE;
 	}
 	}
 	edi->edi_freeing = 1;
 	edi->edi_freeing = 1;
 
 
 	pthread_mutex_unlock(&edi->edi_mutex);
 	pthread_mutex_unlock(&edi->edi_mutex);
-	saHandleDestroy(&event_handle_db, event_handle);
-	saHandleInstancePut(&event_handle_db, event_handle);
+	saHandleDestroy(&event_handle_db, eventHandle);
+	saHandleInstancePut(&event_handle_db, eventHandle);
 
 
 evt_free_done:
 evt_free_done:
 	return error;
 	return error;
@@ -1134,18 +1186,18 @@ evt_free_done:
 
 
 /*
 /*
  * This function may be used to assign writeable event attributes. It takes 
  * This function may be used to assign writeable event attributes. It takes 
- * as arguments an event handle event_handle and the attribute to be set in 
+ * as arguments an event handle eventHandle and the attribute to be set in 
  * the event structure of the event with that handle. Note: The only 
  * the event structure of the event with that handle. Note: The only 
- * attributes that a process can set are the pattern_array, priority, 
- * retention_time and publisher_name attributes.
+ * attributes that a process can set are the patternArray, priority, 
+ * retentionTime and publisherName attributes.
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventAttributesSet(
 saEvtEventAttributesSet(
-	const SaEvtEventHandleT event_handle, 
-	const SaEvtEventPatternArrayT *pattern_array, 
+	const SaEvtEventHandleT eventHandle, 
+	const SaEvtEventPatternArrayT *patternArray, 
 	SaEvtEventPriorityT priority, 
 	SaEvtEventPriorityT priority, 
-	SaTimeT retention_time, 
-	const SaNameT *publisher_name)
+	SaTimeT retentionTime, 
+	const SaNameT *publisherName)
 {
 {
 	SaEvtEventPatternT *oldpatterns;
 	SaEvtEventPatternT *oldpatterns;
 	SaSizeT		    oldnumber;
 	SaSizeT		    oldnumber;
@@ -1153,7 +1205,7 @@ saEvtEventAttributesSet(
 	struct event_data_instance *edi;
 	struct event_data_instance *edi;
 	int i;
 	int i;
 
 
-	error = saHandleInstanceGet(&event_handle_db, event_handle,
+	error = saHandleInstanceGet(&event_handle_db, eventHandle,
 			(void*)&edi);
 			(void*)&edi);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto attr_set_done;
 		goto attr_set_done;
@@ -1161,36 +1213,36 @@ saEvtEventAttributesSet(
 	pthread_mutex_lock(&edi->edi_mutex);
 	pthread_mutex_lock(&edi->edi_mutex);
 
 
 	edi->edi_priority = priority;
 	edi->edi_priority = priority;
-	edi->edi_retention_time = retention_time;
+	edi->edi_retention_time = retentionTime;
 
 
 	/*
 	/*
-	 * publisher_name or pattern_array not allowed to be NULL
+	 * publisherName or patternArray not allowed to be NULL
 	 */
 	 */
-	if (!publisher_name || !pattern_array) {
+	if (!publisherName || !patternArray) {
 			error = SA_AIS_ERR_INVALID_PARAM;
 			error = SA_AIS_ERR_INVALID_PARAM;
 			goto attr_set_unlock;
 			goto attr_set_unlock;
 	}
 	}
 
 
-	edi->edi_pub_name = *publisher_name;
+	edi->edi_pub_name = *publisherName;
 
 
 	oldpatterns = edi->edi_patterns.patterns;
 	oldpatterns = edi->edi_patterns.patterns;
 	oldnumber = edi->edi_patterns.patternsNumber;
 	oldnumber = edi->edi_patterns.patternsNumber;
 	edi->edi_patterns.patterns = 0;
 	edi->edi_patterns.patterns = 0;
 	edi->edi_patterns.patterns = malloc(sizeof(SaEvtEventPatternT) * 
 	edi->edi_patterns.patterns = malloc(sizeof(SaEvtEventPatternT) * 
-					pattern_array->patternsNumber);
+					patternArray->patternsNumber);
 	if (!edi->edi_patterns.patterns) {
 	if (!edi->edi_patterns.patterns) {
 		error = SA_AIS_ERR_NO_MEMORY;
 		error = SA_AIS_ERR_NO_MEMORY;
 		goto attr_set_done_reset;
 		goto attr_set_done_reset;
 	}
 	}
-	edi->edi_patterns.patternsNumber = pattern_array->patternsNumber;
+	edi->edi_patterns.patternsNumber = patternArray->patternsNumber;
 
 
 	/*
 	/*
 	 * copy the patterns from the caller. allocating memory for
 	 * copy the patterns from the caller. allocating memory for
 	 * of all the strings.
 	 * of all the strings.
 	 */
 	 */
-	for (i = 0; i < pattern_array->patternsNumber; i++) {
+	for (i = 0; i < patternArray->patternsNumber; i++) {
 		edi->edi_patterns.patterns[i].pattern = 
 		edi->edi_patterns.patterns[i].pattern = 
-			malloc(pattern_array->patterns[i].patternSize);
+			malloc(patternArray->patterns[i].patternSize);
 		if (!edi->edi_patterns.patterns[i].pattern) {
 		if (!edi->edi_patterns.patterns[i].pattern) {
 			int j;
 			int j;
 			for (j = 0; j < i; j++) {
 			for (j = 0; j < i; j++) {
@@ -1201,10 +1253,10 @@ saEvtEventAttributesSet(
 			goto attr_set_done_reset;
 			goto attr_set_done_reset;
 		}
 		}
 		memcpy(edi->edi_patterns.patterns[i].pattern,
 		memcpy(edi->edi_patterns.patterns[i].pattern,
-			pattern_array->patterns[i].pattern,
-				pattern_array->patterns[i].patternSize);
+			patternArray->patterns[i].pattern,
+				patternArray->patterns[i].patternSize);
 		edi->edi_patterns.patterns[i].patternSize = 
 		edi->edi_patterns.patterns[i].patternSize = 
-			pattern_array->patterns[i].patternSize;
+			patternArray->patterns[i].patternSize;
 	}
 	}
 
 
 	/*
 	/*
@@ -1225,7 +1277,7 @@ attr_set_done_reset:
 	edi->edi_patterns.patternsNumber = oldnumber;
 	edi->edi_patterns.patternsNumber = oldnumber;
 attr_set_unlock:
 attr_set_unlock:
 	pthread_mutex_unlock(&edi->edi_mutex);
 	pthread_mutex_unlock(&edi->edi_mutex);
-	saHandleInstancePut(&event_handle_db, event_handle);
+	saHandleInstancePut(&event_handle_db, eventHandle);
 attr_set_done:
 attr_set_done:
 	return error;
 	return error;
 }
 }
@@ -1241,24 +1293,24 @@ attr_set_done:
  * parameters, if the invoking process provides a NULL reference, the 
  * parameters, if the invoking process provides a NULL reference, the 
  * Availability Management Framework does not return the out value. 
  * Availability Management Framework does not return the out value. 
  * Similarly, it is the responsibility of the invoking process to allocate 
  * Similarly, it is the responsibility of the invoking process to allocate 
- * memory for the pattern_array.
+ * memory for the patternArray.
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventAttributesGet(
 saEvtEventAttributesGet(
-	SaEvtEventHandleT event_handle, 
-	SaEvtEventPatternArrayT *pattern_array, 
+	SaEvtEventHandleT eventHandle, 
+	SaEvtEventPatternArrayT *patternArray, 
 	SaEvtEventPriorityT *priority, 
 	SaEvtEventPriorityT *priority, 
-	SaTimeT *retention_time, 
-	SaNameT *publisher_name, 
-	SaTimeT *publish_time, 
-	SaEvtEventIdT *event_id)
+	SaTimeT *retentionTime, 
+	SaNameT *publisherName, 
+	SaTimeT *publishTime, 
+	SaEvtEventIdT *eventId)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_data_instance *edi;
 	struct event_data_instance *edi;
 	SaSizeT npats;
 	SaSizeT npats;
 	int i;
 	int i;
 
 
-	error = saHandleInstanceGet(&event_handle_db, event_handle,
+	error = saHandleInstanceGet(&event_handle_db, eventHandle,
 			(void*)&edi);
 			(void*)&edi);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto attr_get_done;
 		goto attr_get_done;
@@ -1269,31 +1321,31 @@ saEvtEventAttributesGet(
 	 * Go through the args and send back information if the pointer
 	 * Go through the args and send back information if the pointer
 	 * isn't NULL
 	 * isn't NULL
 	 */
 	 */
-	if (event_id) {
-		*event_id = edi->edi_event_id;
+	if (eventId) {
+		*eventId = edi->edi_event_id;
 	}
 	}
 
 
-	if (publish_time) {
-		*publish_time = edi->edi_pub_time;
+	if (publishTime) {
+		*publishTime = edi->edi_pub_time;
 	}
 	}
 
 
-	if (publisher_name) {
-		*publisher_name = edi->edi_pub_name;
+	if (publisherName) {
+		*publisherName = edi->edi_pub_name;
 	}
 	}
 
 
-	if (retention_time) {
-		*retention_time = edi->edi_retention_time;
+	if (retentionTime) {
+		*retentionTime = edi->edi_retention_time;
 	}
 	}
 
 
 	if (priority) {
 	if (priority) {
 		*priority = edi->edi_priority;
 		*priority = edi->edi_priority;
 	}
 	}
 
 
-	if (!pattern_array) {
+	if (!patternArray) {
 		goto attr_get_unlock;
 		goto attr_get_unlock;
 	}
 	}
 
 
-	npats = min(pattern_array->patternsNumber, 
+	npats = min(patternArray->patternsNumber, 
 				edi->edi_patterns.patternsNumber);
 				edi->edi_patterns.patternsNumber);
 	/*
 	/*
 	 * We set the returned number of patterns to the actual
 	 * We set the returned number of patterns to the actual
@@ -1304,20 +1356,20 @@ saEvtEventAttributesGet(
 	 *
 	 *
 	 * The same thing happens when copying the pattern strings.
 	 * The same thing happens when copying the pattern strings.
 	 */
 	 */
-	pattern_array->patternsNumber = edi->edi_patterns.patternsNumber;
+	patternArray->patternsNumber = edi->edi_patterns.patternsNumber;
 
 
 	for (i = 0; i < npats; i++) {
 	for (i = 0; i < npats; i++) {
-		memcpy(pattern_array->patterns[i].pattern,
+		memcpy(patternArray->patterns[i].pattern,
 			edi->edi_patterns.patterns[i].pattern,
 			edi->edi_patterns.patterns[i].pattern,
-			min(pattern_array->patterns[i].patternSize,
+			min(patternArray->patterns[i].patternSize,
 				edi->edi_patterns.patterns[i].patternSize));
 				edi->edi_patterns.patterns[i].patternSize));
-		pattern_array->patterns[i].patternSize = 
+		patternArray->patterns[i].patternSize = 
 			edi->edi_patterns.patterns[i].patternSize;
 			edi->edi_patterns.patterns[i].patternSize;
 	}
 	}
 
 
 attr_get_unlock:
 attr_get_unlock:
 	pthread_mutex_unlock(&edi->edi_mutex);
 	pthread_mutex_unlock(&edi->edi_mutex);
-	saHandleInstancePut(&event_handle_db, event_handle);
+	saHandleInstancePut(&event_handle_db, eventHandle);
 attr_get_done:
 attr_get_done:
 	return error;
 	return error;
 }
 }
@@ -1329,19 +1381,19 @@ attr_get_done:
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventDataGet(
 saEvtEventDataGet(
-	const SaEvtEventHandleT event_handle, 
-	void *event_data, 
-	SaSizeT *event_data_size)
+	const SaEvtEventHandleT eventHandle, 
+	void *eventData, 
+	SaSizeT *eventDataSize)
 {
 {
 	SaAisErrorT error = SA_AIS_OK;
 	SaAisErrorT error = SA_AIS_OK;
 	struct event_data_instance *edi;
 	struct event_data_instance *edi;
 	SaSizeT xfsize;
 	SaSizeT xfsize;
 
 
-	if (!event_data || !event_data_size) {
+	if (!eventData || !eventDataSize) {
 		goto data_get_done;
 		goto data_get_done;
 	}
 	}
 
 
-	error = saHandleInstanceGet(&event_handle_db, event_handle,
+	error = saHandleInstanceGet(&event_handle_db, eventHandle,
 			(void*)&edi);
 			(void*)&edi);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto data_get_done;
 		goto data_get_done;
@@ -1349,15 +1401,15 @@ saEvtEventDataGet(
 	pthread_mutex_lock(&edi->edi_mutex);
 	pthread_mutex_lock(&edi->edi_mutex);
 
 
 	if (edi->edi_event_data && edi->edi_event_data_size) {
 	if (edi->edi_event_data && edi->edi_event_data_size) {
-		xfsize = min(*event_data_size, edi->edi_event_data_size);
-		*event_data_size = edi->edi_event_data_size;
-		memcpy(event_data, edi->edi_event_data, xfsize);
+		xfsize = min(*eventDataSize, edi->edi_event_data_size);
+		*eventDataSize = edi->edi_event_data_size;
+		memcpy(eventData, edi->edi_event_data, xfsize);
 	} else {
 	} else {
-		*event_data_size = 0;
+		*eventDataSize = 0;
 	}
 	}
 
 
 	pthread_mutex_unlock(&edi->edi_mutex);
 	pthread_mutex_unlock(&edi->edi_mutex);
-	saHandleInstancePut(&event_handle_db, event_handle);
+	saHandleInstancePut(&event_handle_db, eventHandle);
 data_get_done:
 data_get_done:
 	return error;
 	return error;
 }
 }
@@ -1453,8 +1505,8 @@ static uint32_t aisfilt_to_evt_filt(const SaEvtEventFilterArrayT *filters,
 }
 }
 
 
 /*
 /*
- * The saEvtEventPublish() function publishes an event on the channel 
- * designated by channel_handle. The event to be published consists of a 
+ * The saEvtEventPublish() function publishes an event on the associated 
+ * channel. The event to be published consists of a 
  * standard set of attributes (the event header) and an optional data part. 
  * standard set of attributes (the event header) and an optional data part. 
  * Before an event can be published, the publisher process must invoke the 
  * Before an event can be published, the publisher process must invoke the 
  * saEvtEventPatternArraySet() function to set the event patterns. The event 
  * saEvtEventPatternArraySet() function to set the event patterns. The event 
@@ -1480,10 +1532,10 @@ static uint32_t aisfilt_to_evt_filt(const SaEvtEventFilterArrayT *filters,
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventPublish(
 saEvtEventPublish(
-	const SaEvtEventHandleT event_handle, 
-	const void *event_data, 
-	SaSizeT event_data_size,
-	SaEvtEventIdT *eventid)
+	const SaEvtEventHandleT eventHandle, 
+	const void *eventData, 
+	SaSizeT eventDataSize,
+	SaEvtEventIdT *eventId)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_data_instance *edi;
 	struct event_data_instance *edi;
@@ -1496,12 +1548,12 @@ saEvtEventPublish(
 	void   *data_start;
 	void   *data_start;
 	int pub_sleep_trys = PUB_SLEEP_TRYS;
 	int pub_sleep_trys = PUB_SLEEP_TRYS;
 
 
-	if (event_data_size > SA_EVT_DATA_MAX_LEN) {
+	if (eventDataSize > SA_EVT_DATA_MAX_LEN) {
 		error = SA_AIS_ERR_INVALID_PARAM;
 		error = SA_AIS_ERR_INVALID_PARAM;
 		goto pub_done;
 		goto pub_done;
 	}
 	}
 
 
-	error = saHandleInstanceGet(&event_handle_db, event_handle,
+	error = saHandleInstanceGet(&event_handle_db, eventHandle,
 			(void*)&edi);
 			(void*)&edi);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto pub_done;
 		goto pub_done;
@@ -1542,7 +1594,7 @@ saEvtEventPublish(
 	 */
 	 */
 	pattern_size = patt_size(&edi->edi_patterns);
 	pattern_size = patt_size(&edi->edi_patterns);
 
 
-	req = malloc(sizeof(*req) + event_data_size + pattern_size);
+	req = malloc(sizeof(*req) + eventDataSize + pattern_size);
 
 
 	patterns = (struct event_pattern *)req->led_body;
 	patterns = (struct event_pattern *)req->led_body;
 	data_start = (void *)req->led_body + pattern_size;
 	data_start = (void *)req->led_body + pattern_size;
@@ -1560,15 +1612,15 @@ saEvtEventPublish(
 	req->led_patterns_number = edi->edi_patterns.patternsNumber;
 	req->led_patterns_number = edi->edi_patterns.patternsNumber;
 
 
 	req->led_user_data_offset = pattern_size;
 	req->led_user_data_offset = pattern_size;
-	if (event_data && event_data_size) {
-		memcpy(data_start, event_data, event_data_size);
-		req->led_user_data_size = event_data_size;
+	if (eventData && eventDataSize) {
+		memcpy(data_start, eventData, eventDataSize);
+		req->led_user_data_size = eventDataSize;
 	} else {
 	} else {
 		req->led_user_data_size = 0;
 		req->led_user_data_size = 0;
 	}
 	}
 
 
 	req->led_head.id = MESSAGE_REQ_EVT_PUBLISH;
 	req->led_head.id = MESSAGE_REQ_EVT_PUBLISH;
-	req->led_head.size = sizeof(*req) + pattern_size + event_data_size;
+	req->led_head.size = sizeof(*req) + pattern_size + eventDataSize;
 	req->led_svr_channel_handle = eci->eci_svr_channel_handle;
 	req->led_svr_channel_handle = eci->eci_svr_channel_handle;
 	req->led_retention_time = edi->edi_retention_time;
 	req->led_retention_time = edi->edi_retention_time;
 	req->led_publish_time = clustTimeNow();
 	req->led_publish_time = clustTimeNow();
@@ -1610,7 +1662,7 @@ pub_sleep:
 			continue;
 			continue;
 		}
 		}
 
 
-		*eventid = res.iep_event_id;
+		*eventId = res.iep_event_id;
 		break;
 		break;
 	}
 	}
 	if (error == SA_AIS_ERR_TRY_AGAIN) {
 	if (error == SA_AIS_ERR_TRY_AGAIN) {
@@ -1625,7 +1677,7 @@ pub_put2:
 	saHandleInstancePut (&channel_handle_db, edi->edi_channel_handle);
 	saHandleInstancePut (&channel_handle_db, edi->edi_channel_handle);
 pub_put1:
 pub_put1:
 	pthread_mutex_unlock(&edi->edi_mutex);
 	pthread_mutex_unlock(&edi->edi_mutex);
-	saHandleInstancePut(&event_handle_db, event_handle);
+	saHandleInstancePut(&event_handle_db, eventHandle);
 pub_done:
 pub_done:
 	return error;
 	return error;
 }
 }
@@ -1634,7 +1686,7 @@ pub_done:
  * The saEvtEventSubscribe() function enables a process to subscribe for 
  * The saEvtEventSubscribe() function enables a process to subscribe for 
  * events on an event channel by registering one or more filters on that 
  * events on an event channel by registering one or more filters on that 
  * event channel. The process must have opened the event channel, designated 
  * event channel. The process must have opened the event channel, designated 
- * by channel_handle, with the SA_EVT_CHANNEL_SUBSCRIBER flag set for an 
+ * by channelHandle, with the SA_EVT_CHANNEL_SUBSCRIBER flag set for an 
  * invocation of this function to be successful. 
  * invocation of this function to be successful. 
  * The memory associated with the filters is not deallocated by the 
  * The memory associated with the filters is not deallocated by the 
  * saEvtEventSubscribe() function. It is the responsibility of the invoking 
  * saEvtEventSubscribe() function. It is the responsibility of the invoking 
@@ -1648,9 +1700,9 @@ pub_done:
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventSubscribe(
 saEvtEventSubscribe(
-	const SaEvtChannelHandleT channel_handle, 
+	const SaEvtChannelHandleT channelHandle, 
 	const SaEvtEventFilterArrayT *filters, 
 	const SaEvtEventFilterArrayT *filters, 
-	SaEvtSubscriptionIdT subscription_id)
+	SaEvtSubscriptionIdT subscriptionId)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_instance *evti;
 	struct event_instance *evti;
@@ -1659,7 +1711,7 @@ saEvtEventSubscribe(
 	struct res_evt_event_subscribe res;
 	struct res_evt_event_subscribe res;
 	int	sz;
 	int	sz;
 
 
-	error = saHandleInstanceGet(&channel_handle_db, channel_handle,
+	error = saHandleInstanceGet(&channel_handle_db, channelHandle,
 			(void*)&eci);
 			(void*)&eci);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto subscribe_done;
 		goto subscribe_done;
@@ -1702,7 +1754,7 @@ saEvtEventSubscribe(
 	req->ics_head.id = MESSAGE_REQ_EVT_SUBSCRIBE;
 	req->ics_head.id = MESSAGE_REQ_EVT_SUBSCRIBE;
 	req->ics_head.size = sizeof(*req) + sz;
 	req->ics_head.size = sizeof(*req) + sz;
 	req->ics_channel_handle = eci->eci_svr_channel_handle;
 	req->ics_channel_handle = eci->eci_svr_channel_handle;
-	req->ics_sub_id = subscription_id;
+	req->ics_sub_id = subscriptionId;
 	req->ics_filter_size = sz;
 	req->ics_filter_size = sz;
 
 
 	pthread_mutex_lock(&evti->ei_mutex);
 	pthread_mutex_lock(&evti->ei_mutex);
@@ -1727,7 +1779,7 @@ subscribe_put2:
 	saHandleInstancePut(&evt_instance_handle_db, 
 	saHandleInstancePut(&evt_instance_handle_db, 
 					eci->eci_instance_handle);
 					eci->eci_instance_handle);
 subscribe_put1:
 subscribe_put1:
-	saHandleInstancePut(&channel_handle_db, channel_handle);
+	saHandleInstancePut(&channel_handle_db, channelHandle);
 subscribe_done:
 subscribe_done:
 	return error;
 	return error;
 }
 }
@@ -1744,8 +1796,8 @@ subscribe_done:
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventUnsubscribe(
 saEvtEventUnsubscribe(
-	const SaEvtChannelHandleT channel_handle, 
-	SaEvtSubscriptionIdT subscription_id)
+	const SaEvtChannelHandleT channelHandle, 
+	SaEvtSubscriptionIdT subscriptionId)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_instance *evti;
 	struct event_instance *evti;
@@ -1753,7 +1805,7 @@ saEvtEventUnsubscribe(
 	struct req_evt_event_unsubscribe req;
 	struct req_evt_event_unsubscribe req;
 	struct res_evt_event_unsubscribe res;
 	struct res_evt_event_unsubscribe res;
 
 
-	error = saHandleInstanceGet(&channel_handle_db, channel_handle,
+	error = saHandleInstanceGet(&channel_handle_db, channelHandle,
 			(void*)&eci);
 			(void*)&eci);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto unsubscribe_done;
 		goto unsubscribe_done;
@@ -1769,7 +1821,7 @@ saEvtEventUnsubscribe(
 	req.icu_head.size = sizeof(req);
 	req.icu_head.size = sizeof(req);
 
 
 	req.icu_channel_handle = eci->eci_svr_channel_handle;
 	req.icu_channel_handle = eci->eci_svr_channel_handle;
-	req.icu_sub_id = subscription_id;
+	req.icu_sub_id = subscriptionId;
 
 
 	pthread_mutex_lock(&evti->ei_mutex);
 	pthread_mutex_lock(&evti->ei_mutex);
 	error = saSendRetry(evti->ei_fd, &req, sizeof(req), MSG_NOSIGNAL);
 	error = saSendRetry(evti->ei_fd, &req, sizeof(req), MSG_NOSIGNAL);
@@ -1792,7 +1844,7 @@ unsubscribe_put2:
 	saHandleInstancePut(&evt_instance_handle_db, 
 	saHandleInstancePut(&evt_instance_handle_db, 
 					eci->eci_instance_handle);
 					eci->eci_instance_handle);
 unsubscribe_put1:
 unsubscribe_put1:
-	saHandleInstancePut(&channel_handle_db, channel_handle);
+	saHandleInstancePut(&channel_handle_db, channelHandle);
 unsubscribe_done:
 unsubscribe_done:
 	return error;
 	return error;
 }
 }
@@ -1808,8 +1860,8 @@ unsubscribe_done:
  */
  */
 SaAisErrorT 
 SaAisErrorT 
 saEvtEventRetentionTimeClear(
 saEvtEventRetentionTimeClear(
-	const SaEvtChannelHandleT channel_handle, 
-	const SaEvtEventIdT event_id)
+	const SaEvtChannelHandleT channelHandle, 
+	const SaEvtEventIdT eventId)
 {
 {
 	SaAisErrorT error;
 	SaAisErrorT error;
 	struct event_instance *evti;
 	struct event_instance *evti;
@@ -1817,7 +1869,7 @@ saEvtEventRetentionTimeClear(
 	struct req_evt_event_clear_retentiontime req;
 	struct req_evt_event_clear_retentiontime req;
 	struct res_evt_event_clear_retentiontime res;
 	struct res_evt_event_clear_retentiontime res;
 
 
-	error = saHandleInstanceGet(&channel_handle_db, channel_handle,
+	error = saHandleInstanceGet(&channel_handle_db, channelHandle,
 			(void*)&eci);
 			(void*)&eci);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto ret_time_done;
 		goto ret_time_done;
@@ -1833,7 +1885,7 @@ saEvtEventRetentionTimeClear(
 	req.iec_head.size = sizeof(req);
 	req.iec_head.size = sizeof(req);
 
 
 	req.iec_channel_handle = eci->eci_svr_channel_handle;
 	req.iec_channel_handle = eci->eci_svr_channel_handle;
-	req.iec_event_id = event_id;
+	req.iec_event_id = eventId;
 
 
 	pthread_mutex_lock(&evti->ei_mutex);
 	pthread_mutex_lock(&evti->ei_mutex);
 	error = saSendRetry(evti->ei_fd, &req, sizeof(req), MSG_NOSIGNAL);
 	error = saSendRetry(evti->ei_fd, &req, sizeof(req), MSG_NOSIGNAL);
@@ -1856,7 +1908,7 @@ ret_time_put2:
 	saHandleInstancePut(&evt_instance_handle_db, 
 	saHandleInstancePut(&evt_instance_handle_db, 
 					eci->eci_instance_handle);
 					eci->eci_instance_handle);
 ret_time_put1:
 ret_time_put1:
-	saHandleInstancePut(&channel_handle_db, channel_handle);
+	saHandleInstancePut(&channel_handle_db, channelHandle);
 ret_time_done:
 ret_time_done:
 	return error;
 	return error;
 }
 }

+ 407 - 0
test/testevt.c

@@ -51,6 +51,9 @@
  *
  *
  *	test_retention();
  *	test_retention();
  *		Test event retention times.
  *		Test event retention times.
+ *
+ *	test_unlink_channel();
+ *		Test event channel unlink.
  */
  */
 
 
 #include <stdio.h>
 #include <stdio.h>
@@ -116,6 +119,7 @@ SaEvtCallbacksT callbacks = {
 };
 };
 
 
 char channel[256] = "TESTEVT_CHANNEL";
 char channel[256] = "TESTEVT_CHANNEL";
+char unlink_channel[256] = "TESTEVT_UNLINK_CHANNEL";
 SaEvtSubscriptionIdT subscription_id = 0xabcdef;
 SaEvtSubscriptionIdT subscription_id = 0xabcdef;
 SaInvocationT	     open_invocation = 0xaa55cc33;
 SaInvocationT	     open_invocation = 0xaa55cc33;
 unsigned long long test_ret_time = 30000000000ULL; /* 30 seconds */
 unsigned long long test_ret_time = 30000000000ULL; /* 30 seconds */
@@ -2377,6 +2381,408 @@ evt_fin:
 	}
 	}
 	printf("Done\n");
 	printf("Done\n");
 
 
+}
+
+void 
+unlink_chan_callback(SaEvtSubscriptionIdT my_subscription_id,
+		const SaEvtEventHandleT event_handle,
+		const SaSizeT my_event_data_size)
+{
+	SaAisErrorT result;
+	SaUint8T my_priority;
+	SaTimeT my_retention_time;
+	SaNameT my_publisher_name = {0, {0}};
+	SaTimeT my_publish_time;
+	SaEvtEventIdT my_event_id;
+	SaEvtSubscriptionIdT exp_sub_id;
+
+	printf("            unlink_chan_callback called(%d)\n", ++call_count);
+
+	evt_pat_get_array.patternsNumber = 4;
+	result = saEvtEventAttributesGet(event_handle,
+			&evt_pat_get_array,	/* patterns */
+			&my_priority,		/* priority */
+			&my_retention_time,	/* retention time */
+			&my_publisher_name,	/* publisher name */
+			&my_publish_time,	/* publish time */
+			&my_event_id		/* event_id */
+			);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event get attr result: %s\n", result_buf);
+		goto evt_free;
+	}
+
+	if (my_event_id == event_id1) {
+		exp_sub_id = sub1;
+	} else if (my_event_id == event_id2) {
+		exp_sub_id = sub2;
+	} else {
+		printf("ERROR: Received event %llx but not sent\n", my_event_id);
+		goto evt_free;
+	}
+
+	if (my_subscription_id != exp_sub_id) {
+		printf("ERROR: sub ID: e=%x, a=%x\n", 
+				exp_sub_id, my_subscription_id);
+		goto evt_free;
+	}
+
+evt_free:
+	result = saEvtEventFree(event_handle);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event free result: %s\n", result_buf);
+	}
+}
+
+/*
+ * Test channel unlink operations.
+ * 1. Unlink channel.
+ * 2. Open/create a channel, close channel, open channel.
+ * 3. unlink channel, Open channel.
+ * 4. Open/create, unlink channel, close channel, open channel.
+ * 5. Open/create a channel, unlink channel, open/create channel, send
+ *    event on each.
+ * 6. unlink all, close all.
+ */
+SaEvtCallbacksT unlink_callbacks = {
+	open_callback,
+	unlink_chan_callback
+};
+void
+test_unlink_channel()
+{
+	SaEvtHandleT handle;
+	SaEvtChannelHandleT channel_handle1;
+	SaEvtChannelHandleT channel_handle2;
+	SaEvtEventHandleT	event_handle1;
+	SaEvtEventHandleT	event_handle2;
+	SaEvtChannelOpenFlagsT flags1, flags2;
+	SaNameT channel_name;
+	int result;
+
+	struct pollfd pfd;
+	int nfd;
+	int fd;
+	int timeout = 5000;
+	 
+	flags1 = SA_EVT_CHANNEL_PUBLISHER |
+		SA_EVT_CHANNEL_SUBSCRIBER |
+		SA_EVT_CHANNEL_CREATE;
+
+	flags2 = SA_EVT_CHANNEL_PUBLISHER |
+		SA_EVT_CHANNEL_SUBSCRIBER;
+
+
+	printf("Test Channel Unlink operations:\n");
+
+	result = saEvtInitialize (&handle, &unlink_callbacks, versions[0].version);
+
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: Event Initialize result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	/*
+	 * 1. Unlink channel.
+	 *
+	 * Unlink previously opened channel should return OK.
+	 * Unlink of non-existent channel should return error.
+	 */
+	printf("       1 Channel unlink:\n");
+
+	strcpy(channel_name.value, channel);
+	channel_name.length = strlen(channel);
+	result = saEvtChannelUnlink(handle, &channel_name);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel unlink(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	strcpy(channel_name.value, unlink_channel);
+	channel_name.length = strlen(unlink_channel);
+	result = saEvtChannelUnlink(handle, &channel_name);
+	if (result != SA_AIS_ERR_NOT_EXIST) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel unlink(2) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	/*
+ 	 * 2. Open/create a channel, close channel, open channel.
+	 *
+	 * Open/create the channel.
+	 * Close the channel.
+	 * Open without create.  This should succeed in the B spec.
+	 */
+	printf("       2 Channel open/close/open:\n");
+
+	result = saEvtChannelOpen(handle, &channel_name, flags1, 0,
+				&channel_handle1);
+
+
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel open(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelClose(channel_handle1);
+	
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel close(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelOpen(handle, &channel_name, flags2, 0,
+				&channel_handle1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel open(2) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	/*
+ 	 * 3. unlink channel, Open channel, close channel
+	 *
+	 * Unlink the channel.  Should mark for deletion but not
+	 *		delete it since it is already open.
+	 * Open the channel without create. This should fail since
+	 *		the channel is marked for deletion and a new version 
+	 *		hasn't been created.
+	 * Close channel.
+	 */
+	printf("       3 Channel unlink/open/close:\n");
+
+	result = saEvtChannelUnlink(handle, &channel_name);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel unlink result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelOpen(handle, &channel_name, flags2, 0,
+				&channel_handle2);
+	if (result != SA_AIS_ERR_NOT_EXIST) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel open result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+	result = saEvtChannelClose(channel_handle1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel close(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	/*
+	 *
+ 	 * 4. Open/create, unlink channel, close channel, open channel.
+	 *
+	 * Open/create the channel.
+	 * unlink the channel.
+	 * close the channel.  This should delete the channel instance since
+	 *		it was marked for deletion.
+	 * open the channel without create.  This should fail since the
+	 *		channel doesn't exist anymore.
+	 */
+	printf("       4 Channel open/unlink/close/open:\n");
+	result = saEvtChannelOpen(handle, &channel_name, flags1, 0,
+				&channel_handle1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel open(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelUnlink(handle, &channel_name);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel unlink result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelClose(channel_handle1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel close(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelOpen(handle, &channel_name, flags2, 0,
+				&channel_handle1);
+	if (result != SA_AIS_ERR_NOT_EXIST) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel open(2) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	/*
+	 * 5. Open/create a channel, unlink channel, open/create channel, send 
+	 * 		event on each.
+	 *
+	 * Open/create.
+	 * unlink.  Mark for deletion.
+	 * open/create. Create new channel of same name.
+	 * send event on each open channel.  The events should be received on
+	 * separate channels.
+	 */
+	printf("       5 Channel open/unlink/open/send:\n");
+
+	result = saEvtChannelOpen(handle, &channel_name, flags1, 0,
+				&channel_handle1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel open result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelUnlink(handle, &channel_name);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel unlink result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtChannelOpen(handle, &channel_name, flags1, 0,
+				&channel_handle2);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel open result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtEventSubscribe(channel_handle1,
+			&subscribe_filters,
+			sub1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel subscribe(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtEventSubscribe(channel_handle2,
+			&subscribe_filters,
+			sub2);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: channel subscribe(2) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	retention_time = 0ULL;
+	result = saEvtEventAllocate(channel_handle1, &event_handle1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event allocate(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+	result = saEvtEventAttributesSet(event_handle1,
+			&evt_pat_set_array,
+			TEST_PRIORITY,
+			retention_time,
+			&test_pub_name);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event set(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtEventAllocate(channel_handle2, &event_handle2);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event allocate(2) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+	result = saEvtEventAttributesSet(event_handle2,
+			&evt_pat_set_array,
+			TEST_PRIORITY,
+			retention_time,
+			&test_pub_name);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event set(2) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	result = saEvtEventPublish(event_handle1, 0,  0, &event_id1);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event publish(1) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+	result = saEvtEventPublish(event_handle2, 0,  0, &event_id2);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: event publish(2) result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+
+	result = saEvtSelectionObjectGet(handle, &fd);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: select object get result: %s\n", result_buf);
+		goto unlink_exit;
+	}
+
+	/*
+	 * We should see a total of two events processed, not four
+	 * as if both events were recevied on both channels.
+	 */
+	call_count = 0;
+	do {
+		pfd.fd = fd;
+		pfd.events = POLLIN;
+		nfd = poll(&pfd, 1, timeout);
+		if (nfd <= 0) {
+			if (nfd < 0) {
+				perror("ERROR: poll error");
+				goto unlink_exit;
+			}
+		} else {
+
+			result = saEvtDispatch(handle, SA_DISPATCH_ONE);
+			if (result != SA_AIS_OK) {
+				get_sa_error(result, result_buf, result_buf_len);
+				printf("ERROR: saEvtDispatch %s\n", result_buf);
+				goto unlink_exit;
+			}
+		}
+	} while (nfd > 0);
+
+	if (call_count != 2) {
+		printf("ERROR: processed %d events\n", call_count);
+		goto unlink_exit;
+	}
+		
+
+	/*
+	 * 6. unlink all, close all.
+	 *
+	 * close all open channels.
+	 * unlink the channel.
+	 * open without create the channel.  Verify that the channel no 
+	 * 		longer exists.
+	 */
+	printf("       6 Channel unlink all/close all/open:\n");
+
+unlink_exit:
+	saEvtChannelClose(channel_handle1);
+	saEvtChannelClose(channel_handle2);
+	saEvtChannelUnlink(handle, &channel_name);
+	result = saEvtFinalize(handle);
+	if (result != SA_AIS_OK) {
+		get_sa_error(result, result_buf, result_buf_len);
+		printf("ERROR: Event Finalize result: %s\n", result_buf);
+	}
+
+	printf("Done\n");
+
 }
 }
 int main (void)
 int main (void)
 {
 {
@@ -2387,6 +2793,7 @@ int main (void)
 	test_multi_channel2();
 	test_multi_channel2();
 	test_multi_channel3();
 	test_multi_channel3();
 	test_retention();
 	test_retention();
+	test_unlink_channel();
 
 
 	return (0);
 	return (0);
 }
 }