rev 670 - in trunk: include/prothon src

SVN User <[email protected]> Sun, 27 Jun 2004 19:21:33 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-27 19:21:31 -0400 (Sun, 27 Jun 2004)
New Revision: 670

Modified:
   trunk/include/prothon/prothon.h
   trunk/src/builtins-dict.c
   trunk/src/lock.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/symbol.c
Log:
object modification notification feature implemented but not testred

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-06-27 21:07:54 UTC (rev 669)
+++ trunk/include/prothon/prothon.h	2004-06-27 23:21:31 UTC (rev 670)
@@ -477,6 +477,7 @@
 	ATTRS_,
 	PROTOS_,
 	COMMAND_,
+	NOTIFYCALLBACK_,
 
 	SYM_ENUM_COUNT
 } sym_enum_t;

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-06-27 21:07:54 UTC (rev 669)
+++ trunk/src/builtins-dict.c	2004-06-27 23:21:31 UTC (rev 670)
@@ -117,17 +117,14 @@
 
 //********************************* hash_value ********************************
 i32_t hash_value(isp ist, obj_p key_in) {
-	if (has_proto(ist, key_in, OBJ(INT_PROTO)))
-		return ((i32_t) key_in->data.i64);
-	else {
-		obj_p hash_obj = call_func0(ist, key_in, SYM(HASH_));
-		if_exc_return 0;
-		if (!is_immutable(key_in)) {
-			raise_exception(ist, OBJ(TYPE_EXC), "dictionary keys must be immutable");
-			return 0;
-		}
-		return hash_obj->data.i32[0];
+	obj_p hash_obj;
+	if (!is_immutable(key_in)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "dictionary keys must be immutable");
+		return 0;
 	}
+	hash_obj = call_func0(ist, key_in, SYM(HASH_));
+	if_exc_return 0;
+	return hash_obj->data.i32[0];
 }
 
 //********************************* dict_add **********************************

Modified: trunk/src/lock.c
===================================================================
--- trunk/src/lock.c	2004-06-27 21:07:54 UTC (rev 669)
+++ trunk/src/lock.c	2004-06-27 23:21:31 UTC (rev 670)
@@ -71,45 +71,92 @@
 
 int obj_wrlock_waiting;
 
-DECLARE_PR_LOCK(notify_lock);
-obj_p notify_dict;
+DECLARE_PR_LOCK(del_notify_lock_var);
 
-//********************************* init_notify *******************************
-void init_notify(isp ist) {
-	pr_lock(&notify_lock);
-	notify_dict = new_dict_obj(ist, 10);
-	pr_unlock(&notify_lock);
-}
+//********************************* notify ************************************
+void notify(isp ist, obj_p obj, int flag) {
+	int i, llen;
+	obj_p callback_list, arr[2] = {OBJ(NOKEY), NEW_INT(flag)};
 
-//********************************* read_notify *******************************
-void read_notify(isp ist, obj_p obj){
-	pr_lock(&notify_lock);
-
-
-	pr_unlock(&notify_lock);
+	if (callback_list = get_attr(ist, obj, SYM(NOTIFYCALLBACK_))) {
+		llen = (int) list_len(ist, callback_list);
+		for (i=0; i < llen; i += 2)
+			if (int2i32t(ist, list_item(ist, callback_list, i)) & flag)
+				call_func(ist, NULL, list_item(ist, callback_list, i+1), 2, arr, NULL);
+	}
 }
 
-//********************************* write_notify ******************************
-void write_notify(isp ist, obj_p obj){
-	pr_lock(&notify_lock);
-
-
-	pr_unlock(&notify_lock);
-}
-
 //********************************* delete_notify *****************************
 void delete_notify(isp ist, obj_p obj){
 	int del_notify;
 	get_wrlock(obj, FALSE);
 	del_notify = obj->del_notify;
 	free_wrlock(obj);
-	if (!del_notify) return;
-	pr_lock(&notify_lock);
-	
+	if (del_notify) {
+		del_notify_lock();
+		notify(ist, obj, DELETE_NOTIFY);
+		del_notify_unlock();
+	}
+}
 
-	pr_unlock(&notify_lock);
+//********************************* add_notification **************************
+void add_notification(isp ist, obj_p obj, obj_p callback_func, int flags) {
+	int i, llen, new_list = FALSE;
+	obj_p callback_list = get_attr(ist, obj, SYM(NOTIFYCALLBACK_));
+	if (!callback_list) {
+		callback_list = NEW_LIST(2);
+		new_list = TRUE;
+	}
+	llen = (int) list_len(ist, callback_list);
+	for (i=0; i < llen; i += 2) {
+		if (list_item(ist, callback_list, i+1) == callback_func) {
+			flags |= int2i32t(ist, list_item(ist, callback_list, i));
+			list_item_set(ist, callback_list, i, NEW_INT(flags));
+			goto done;
+		}
+	}
+	list_append(ist, callback_list, NEW_INT(flags));
+	list_append(ist, callback_list, callback_func);
+	if (new_list)
+		set_attr(ist, obj, SYM(NOTIFYCALLBACK_), callback_list);
+done:
+	get_wrlock(obj, FALSE);
+	if (flags & READ_NOTIFY)   obj->rd_notify = TRUE;
+	if (flags & WRITE_NOTIFY)  obj->wr_notify = TRUE;
+	if (flags & DELETE_NOTIFY) obj->del_notify = TRUE;
+	free_wrlock(obj);
 }
 
+//********************************* clr_notification **************************
+void del_notification(isp ist, obj_p obj, obj_p callback_func) {
+	list_p selfp;
+	int i, llen, flags;
+	obj_p callback_list = get_attr(ist, obj, SYM(NOTIFYCALLBACK_));
+	if (!callback_list) return;
+	write_lock(ist, callback_list);
+	selfp = callback_list->data.ptr;
+	while (TRUE) {
+		llen  = (int) lstplen(selfp);
+		for (i=0; i < llen; i += 2)
+			if (listitem(callback_list, i+1) == callback_func) break;
+		if (i == llen) break; 
+		if (i < llen-2)
+			memmove( selfp->item+i, selfp->item+i+2, 
+					(llen - 2 - (size_t)i) * sizeof(obj_p) ); 
+		lstplen(selfp) -= 2;
+	}
+	write_unlock(ist, callback_list); 
+	llen = (int) list_len(ist, callback_list);
+	flags = 0;
+	for(i=0; i < llen; i += 2)
+		flags |= int2i32t(ist, list_item(ist, callback_list, i));
+	get_wrlock(obj, FALSE);
+	if (flags & READ_NOTIFY)   obj->rd_notify  = TRUE; else obj->rd_notify  = FALSE; 
+	if (flags & WRITE_NOTIFY)  obj->wr_notify  = TRUE; else obj->wr_notify  = FALSE;
+	if (flags & DELETE_NOTIFY) obj->del_notify = TRUE; else obj->del_notify = FALSE;
+	free_wrlock(obj);
+}
+
 //********************************* get_wrlock ********************************
 void get_wrlock(obj_p obj, int force_wait) {
 	if (!force_wait && lock((obj)->wrlock)) return;
@@ -144,7 +191,7 @@
 	clist_push(lockstack, obj);
 	obj->rdlock_cnt++;
 	obj->state = OBJ_STATE_NEW_OR_MARKED;
-	if (obj->rd_notify) read_notify(ist, obj);
+	if (obj->rd_notify) notify(ist, obj, READ_NOTIFY);
 	free_wrlock(obj);
 	return TRUE;
 }
@@ -170,7 +217,7 @@
 	clist_push(lockstack, obj);
 	obj->rdlock_cnt++;
 	obj->state = OBJ_STATE_NEW_OR_MARKED;
-	if (obj->rd_notify) read_notify(ist, obj);
+	if (obj->rd_notify) notify(ist, obj, READ_NOTIFY);
 	free_wrlock(obj);
 	return FALSE;
 }
@@ -211,7 +258,7 @@
 		free_wrlock(obj);
 		return FALSE;
 	}
-	if (obj->wr_notify) write_notify(ist, obj);
+	if (obj->wr_notify) notify(ist, obj, WRITE_NOTIFY);
 	return TRUE;
 }
 
@@ -247,7 +294,7 @@
 		apr_thread_mutex_unlock(write_mutex);
 		obj->rdlock_cnt += sav_cnt;
 	}
-	if (obj->wr_notify) write_notify(ist, obj);
+	if (obj->wr_notify) notify(ist, obj, WRITE_NOTIFY);
 	return FALSE;
 }
 

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-06-27 21:07:54 UTC (rev 669)
+++ trunk/src/object.c	2004-06-27 23:21:31 UTC (rev 670)
@@ -248,7 +248,6 @@
 	OBJ(SYMBOLS)            = NEW_DICT(SYM_ENUM_COUNT+100);
 
 	init_symbol(ist);
-	init_notify(ist);
 
 	set_obj_doc(OBJ(SYMBOLS), "Symbols: dictionary of all symbol objects");
 

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-06-27 21:07:54 UTC (rev 669)
+++ trunk/src/object.h	2004-06-27 23:21:31 UTC (rev 670)
@@ -184,8 +184,17 @@
 #define SEQ_TYPE_TUPLE          2
 #define SEQ_TYPE_LIST           3
 
-extern obj_p notify_dict;
-void init_notify(isp ist);
+#define READ_NOTIFY		1
+#define WRITE_NOTIFY	2
+#define	DELETE_NOTIFY	4
+
+void add_notification(isp ist, obj_p obj, obj_p callback_func, int flags);
+void del_notification(isp ist, obj_p obj, obj_p callback_func);
+
 void delete_notify(isp ist, obj_p obj);
 
+extern  pr_lock_t		    del_notify_lock_var;
+#define del_notify_lock()	pr_lock(&del_notify_lock_var)
+#define del_notify_unlock()	pr_unlock(&del_notify_lock_var)
+
 #endif  // #define OBJECT_H

Modified: trunk/src/symbol.c
===================================================================
--- trunk/src/symbol.c	2004-06-27 21:07:54 UTC (rev 669)
+++ trunk/src/symbol.c	2004-06-27 23:21:31 UTC (rev 670)
@@ -156,7 +156,8 @@
 	{ "name_",          0},
 	{ "attrs_",         0},
 	{ "protos_",        0},
-	{ "command_",       0}
+	{ "command_",       0},
+	{ "notifyCallback_",0}
 };
 
 typedef struct trie_node_s* trie_p;