rev 164 - in trunk: include/prothon src
SVN User <[email protected]>
| Newsgroups | gmane.comp.lang.prothon.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: mark
Date: 2004-03-27 17:36:25 -0500 (Sat, 27 Mar 2004)
New Revision: 164
Modified:
trunk/include/prothon/prothon.h
trunk/src/lock.c
trunk/src/lock.h
trunk/src/main.c
trunk/src/memory_mgr.c
trunk/src/object.c
trunk/src/sys.c
Log:
added set_unmutable and clr_unmutable, fixed os_thread_2_apr
Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h 2004-03-27 22:13:09 UTC (rev 163)
+++ trunk/include/prothon/prothon.h 2004-03-27 22:36:25 UTC (rev 164)
@@ -850,11 +850,22 @@
// does no harm to add extra matching calls). Also, the write_lock and write_unlock
// routines in DLLs handle disabling the read-locks before calling write_locks.
// See the routine read_unlock_write_lock in object.c.
+// Note: If object has unmutable bit set, then read_lock call is effectively a no-op
+// and write-lock call will cause an exception.
void read_lock (isp ist, obj_p obj);
void read_unlock (isp ist, obj_p obj);
void write_lock (isp ist, obj_p obj);
void write_unlock (isp ist, obj_p obj);
+//************************** UNMUTABLE BIT ***********************************
+// Each object has a bit called unmutable. This bit is effectively a write-protect
+// bit for the object. When set the object cannot be modified. Any attempt
+// to write_lock the object with unmutable set will cause an exception. This bit
+// also speeds up processing since the read_lock becomes a no_op when this bit
+// is set. This bit is set for many common data types such as Int, String, Etc.
+void set_unmutable(obj_p obj);
+void clr_unmutable(obj_p obj);
+
//************************** DELETE LOCKING ***********************************
// The garbage collection process in the memory manager will delete any object
// that isn't recursively contained in the root globals container. This means
@@ -866,7 +877,7 @@
// hierarchy and then call del_unlock(obj) to clear this bit. You can also set
// the bit manually if you need to remove an object from the hierarchy temporarily.
// WARNING: Leaving this bit set will create a memory leak just like not calling
-// free().
+// free() from a malloc() call in C.
void del_lock (obj_p obj);
void del_unlock(obj_p obj);
Modified: trunk/src/lock.c
===================================================================
--- trunk/src/lock.c 2004-03-27 22:13:09 UTC (rev 163)
+++ trunk/src/lock.c 2004-03-27 22:36:25 UTC (rev 164)
@@ -91,17 +91,17 @@
int read_lock_try(isp ist, obj_p obj) {
if (!lock((obj)->wrlock)) return PR_FALSE;
if (obj->unmutable) {
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return PR_TRUE;
}
if (obj->wrlock_req_cnt) {
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return PR_FALSE;
}
clist_push(lockstack, obj);
obj->rdlock_cnt++;
obj->state = OBJ_STATE_NEW_OR_MARKED;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return PR_TRUE;
}
@@ -109,19 +109,19 @@
void read_lock(isp ist, obj_p obj) {
get_wrlock(obj, NO_WAIT);
if (obj->unmutable) {
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return;
}
if (obj->wrlock_req_cnt && !clist_in(lockstack, obj)) {
while(obj->wrlock_req_cnt) {
- free_obj_wrlock(obj);
+ free_wrlock(obj);
get_wrlock(obj, WAIT);
}
}
clist_push(lockstack, obj);
obj->rdlock_cnt++;
obj->state = OBJ_STATE_NEW_OR_MARKED;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return;
}
@@ -130,16 +130,16 @@
int write_ready_flag;
get_wrlock(obj, NO_WAIT);
if (obj->unmutable) {
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return;
}
write_ready_flag = !(--(obj->rdlock_cnt)) && obj->wrlock_req_cnt;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
if (write_ready_flag) apr_thread_cond_broadcast(write_cond);
if (clist_pop_item(lockstack, obj)) {
get_wrlock(obj, NO_WAIT);
obj->rdlock_cnt++;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
raise_exception(ist, OBJ(LOCK_EXC), "read_unlock performed on a non-read_locked object");
}
}
@@ -149,11 +149,11 @@
if (!lock((obj)->wrlock)) return PR_FALSE;
if (obj->unmutable) {
raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an unmutable object");
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return PR_FALSE;
}
if (obj->rdlock_cnt || obj->wrlock_req_cnt) {
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return PR_FALSE;
}
obj->long_wrlock = PR_TRUE;
@@ -167,7 +167,7 @@
if (obj->unmutable) {
raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an unmutable object");
// something should be done to stop code from actually modifying object XXX
- free_obj_wrlock(obj);
+ free_wrlock(obj);
return;
}
if(obj->rdlock_cnt) {
@@ -178,7 +178,7 @@
apr_thread_mutex_lock(write_mutex);
while (obj->rdlock_cnt) {
obj->wrlock_req_cnt++;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
apr_thread_cond_timedwait(write_cond, write_mutex, PAUSE_MS*1000);
get_wrlock(obj, NO_WAIT);
obj->wrlock_req_cnt--;
@@ -205,7 +205,7 @@
pr_unlock(&to_be_scanned_list_lock);
}
write_ready_flag = obj->wrlock_req_cnt;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
if (write_ready_flag) apr_thread_cond_broadcast(write_cond);
}
@@ -258,12 +258,12 @@
void del_lock(obj_p obj) {
get_wrlock(obj, NO_WAIT);
obj->del_locked = PR_TRUE;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
}
//********************************* del_unlock ********************************
void del_unlock(obj_p obj) {
get_wrlock(obj, NO_WAIT);
obj->del_locked = PR_FALSE;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
}
Modified: trunk/src/lock.h
===================================================================
--- trunk/src/lock.h 2004-03-27 22:13:09 UTC (rev 163)
+++ trunk/src/lock.h 2004-03-27 22:36:25 UTC (rev 164)
@@ -93,7 +93,7 @@
extern apr_thread_cond_t *write_cond;
extern apr_thread_mutex_t *write_mutex;
-#define free_obj_wrlock(obj) \
+#define free_wrlock(obj) \
unlock((obj)->wrlock); \
if (obj_wrlock_waiting) \
apr_thread_cond_broadcast(obj_wrlock_cond)
Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c 2004-03-27 22:13:09 UTC (rev 163)
+++ trunk/src/main.c 2004-03-27 22:36:25 UTC (rev 164)
@@ -150,9 +150,11 @@
apr_thread_t *res = NULL;
pr_lock(&thread_registry_lock);
- for (i = 0; i < clist_len(thread_registry); i += 2) {
- if (clist_item(thread_registry, i) == (void *)os_thread) {
- res = clist_item(thread_registry, i+1);
+ for (i = 0; i < clist_len(thread_registry); i++) {
+ obj_p thread_obj = clist_item(thread_registry, i);
+ pr_thread_p thread_ptr = thread_obj->data.ptr;
+ if (thread_ptr->apr_os_thread == os_thread) {
+ res = thread_ptr->apr_thread;
break;
}
}
Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c 2004-03-27 22:13:09 UTC (rev 163)
+++ trunk/src/memory_mgr.c 2004-03-27 22:36:25 UTC (rev 164)
@@ -91,7 +91,7 @@
apr_thread_mutex_lock(write_mutex);
while (obj->rdlock_cnt) {
obj->wrlock_req_cnt++;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
apr_thread_cond_timedwait(write_cond, write_mutex, PAUSE_MS*1000);
get_wrlock(obj, NO_WAIT);
obj->wrlock_req_cnt--;
@@ -107,7 +107,7 @@
assert(obj->wrlock);
obj->long_wrlock = PR_FALSE;
write_ready_flag = obj->wrlock_req_cnt;
- free_obj_wrlock(obj);
+ free_wrlock(obj);
if (write_ready_flag) apr_thread_cond_broadcast(write_cond);
}
Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c 2004-03-27 22:13:09 UTC (rev 163)
+++ trunk/src/object.c 2004-03-27 22:36:25 UTC (rev 164)
@@ -131,8 +131,8 @@
OBJ(OBJECT) = new_object(NULL);
OBJ(OBJECT)->attr_proto.proto = OBJ(OBJECT);
OBJ(NONE) = new_object(NULL);
- OBJ(PR_TRUE) = new_object(NULL);
- OBJ(PR_FALSE) = new_object(NULL);
+ OBJ(PR_TRUE) = new_object(NULL);
+ OBJ(PR_FALSE) = new_object(NULL);
OBJ(INT_PROTO) = new_object(NULL);
OBJ(LONG_PROTO) = new_object(NULL);
OBJ(FLOAT_PROTO) = new_object(NULL);
@@ -308,6 +308,20 @@
pr_free(obj);
}
+//********************************* set_unmutable *****************************
+void set_unmutable(obj_p obj){
+ get_wrlock(obj, NO_WAIT);
+ obj->unmutable = TRUE;
+ free_wrlock(obj);
+}
+
+//********************************* clr_unmutable *****************************
+void clr_unmutable(obj_p obj){
+ get_wrlock(obj, NO_WAIT);
+ obj->unmutable = FALSE;
+ free_wrlock(obj);
+}
+
//********************************* raise_exception ***************************
void raise_exception(isp ist, obj_p proto_obj, char* comment){
if (!proto_obj) proto_obj = OBJ(EXCEPTION);
Modified: trunk/src/sys.c
===================================================================
--- trunk/src/sys.c 2004-03-27 22:13:09 UTC (rev 163)
+++ trunk/src/sys.c 2004-03-27 22:36:25 UTC (rev 164)
@@ -84,12 +84,17 @@
#include <apr_strings.h>
static obj_p sys_exit(isp ist, obj_p self, int pcnt, obj_p* parms, obj_p dlocals) {
+ apr_thread_t* apr_thread;
if (!has_proto(ist, parms[1], OBJ(INT_PROTO))) {
raise_exception(ist, OBJ(TYPE_EXC), "Sys.exit parameter must be an integer");
return NULL;
}
main_threads_running--;
- apr_thread_exit(os_thread_2_apr(apr_os_thread_current()), (int)parms[1]->data.i64);
+ apr_thread = os_thread_2_apr(apr_os_thread_current());
+ if (!apr_thread) {
+ raise_exception(ist, OBJ(INTERNAL_EXC), "sys_exit: no thread to exit");
+ } else
+ apr_thread_exit(apr_thread, (int)parms[1]->data.i64);
return NULL;
}