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;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.