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(¬ify_lock);
- notify_dict = new_dict_obj(ist, 10);
- pr_unlock(¬ify_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(¬ify_lock);
-
-
- pr_unlock(¬ify_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(¬ify_lock);
-
-
- pr_unlock(¬ify_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(¬ify_lock);
-
+ if (del_notify) {
+ del_notify_lock();
+ notify(ist, obj, DELETE_NOTIFY);
+ del_notify_unlock();
+ }
+}
- pr_unlock(¬ify_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;