rev 289 - in trunk: include/prothon pr src

SVN User <[email protected]>
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-05 22:35:08 -0400 (Mon, 05 Apr 2004)
New Revision: 289

Modified:
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/pr/test.pr
   trunk/src/builtins-core.c
   trunk/src/builtins-int.c
   trunk/src/interp.c
   trunk/src/interp.h
   trunk/src/lock.c
   trunk/src/main.c
   trunk/src/memory_mgr.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/sys.c
   trunk/src/thread.c
Log:
all security code is implemented and working, objects are
set to guest access level so everything can run

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/include/prothon/prothon.h	2004-04-06 02:35:08 UTC (rev 289)
@@ -83,12 +83,12 @@
 
 //**************************** DEBUG DEFINITIONS *********************************
 
-//#define DEBUG_THREADS
-//#define DEBUG_MEM_MGR
-//#define TRACE_PARSER
-//#define TRACE_INTERPRETER
-//#define DUMP_MODULE_CODE
-//#define DUMP_OBJECTS_AT_END
+#define DEBUG_THREADS
+#define DEBUG_MEM_MGR
+#define TRACE_PARSER
+#define TRACE_INTERPRETER
+#define DUMP_MODULE_CODE
+#define DUMP_OBJECTS_AT_END
 
 //************************* BASIC TYPE DEFINITIONS ********************************
 
@@ -97,9 +97,9 @@
 typedef apr_int32_t		i32_t;
 typedef apr_int64_t		i64_t;
 typedef apr_byte_t		u8_t;
-typedef apr_uint16_t		u16_t;
-typedef apr_uint32_t		u32_t;
-typedef apr_uint64_t		u64_t;
+typedef apr_uint16_t	u16_t;
+typedef apr_uint32_t	u32_t;
+typedef apr_uint64_t	u64_t;
 
 #ifdef WIN32
 #define MAX_INT_VAL		0x7fffffffffffffff
@@ -107,9 +107,6 @@
 #define MAX_INT_VAL		0x7fffffffffffffffLL
 #endif
 
-typedef i32_t			attr_key_t;
-typedef struct obj_s*	obj_p;
-
 #ifndef min
 # define min(a,b) (((a)<(b)) ? (a) : (b))
 #endif /* min */
@@ -120,6 +117,9 @@
 // neg key value means entry is deleted
 #define ENTRY_DELETED	-1
 
+typedef i32_t			attr_key_t;
+typedef struct obj_s*	obj_p;
+
 typedef struct {
 	attr_key_t	key;
 	obj_p		value;
@@ -161,18 +161,28 @@
 	void*		ptr;
 } obj_data_t;
 
+typedef u8_t access_t;
+
+#define ACC_GUEST	0
+#define ACC_USER1	1
+#define ACC_USER2	2
+#define ACC_SYSTEM	3
+
+
 typedef struct obj_s {
+	obj_state_t		state			:3;
+	obj_type_t		data_type		:3;
 	u8_t			imm_data_len	:4;
-	obj_type_t		data_type		:3;
-	obj_state_t		state			:3;
+	access_t		rd_access		:2;	
+	access_t		wr_access		:2;	
 	u8_t			immutable		:1;
-	u8_t			del_locked		:1;
 	u8_t			scanned			:1;	
+	u8_t			archived		:1;	
 	u8_t 			has_attrs		:1;
-	u8_t			archived		:1;	
+	u8_t			del_locked		:1;
 	u8_t			long_wrlock		:1;	
-	u8_t			rdlock_cnt;
-	u8_t			wrlock_req_cnt;
+	u8_t			rdlock_cnt		:6;
+	u8_t			wrlock_req_cnt	:6;
 	apr_uint32_t	wrlock;
 	attr_proto_t	attr_proto;
 	obj_data_t		data;
@@ -186,11 +196,14 @@
 
 typedef pr_str_t* pr_str_p;
 
+typedef struct interp_state_s* isp;
+
 typedef struct {
 	apr_os_thread_t		apr_os_thread;
 	apr_thread_t*		apr_thread;
 	int					main_id;
 	int					running;
+	isp					ist;
 } pr_thread_t;
 
 typedef pr_thread_t* pr_thread_p;
@@ -246,8 +259,9 @@
 	IOEXCEPTION,		//  
 	FUNCNOTFOUND_EXC,	//  
 	FILENOTFOUND_EXC,	//  
-	STOP_ITERATION_EXC,		//  
+	STOP_ITERATION_EXC,	//  
 	LOCK_EXC,			//  
+	PERMISSION_EXC,		//
 
 // constants
 	ZERO_INT,			//  
@@ -385,18 +399,20 @@
 // pass that ist value on in any call to a Prothon function.  The C code is only
 // allowed to call one Prothon function at a time with that value in the same thread.
 // ist also provides the exception mechanism (see EXCEPTION section below). 
+// Access determines the access priveleges the thread has in accessing objects.
+// Each object has a threshold access for reading and for writing.  See the definition
+// of struct obj_s.
 // NOTE: The pointer type "isp" and the variable name "ist" were chosen to be short 
 // because they are used in almost every function call in Prothon C code.  You must 
 // use these names as given because many macros expect these names.  Don't worry, 
 // you will have them memorized in no time.
-typedef struct {
+typedef struct interp_state_s {
+	access_t				access;
 	void*					lock_stack;
 	struct exec_frame_t*	frame;
 	obj_p					exception_obj;
 } interp_state_t;
 
-typedef interp_state_t* isp;
-
 // NEW_OBJECT: Create a new empty object with only proto pointer
 // Creates a new empty object with a single proto obj.  If proto is
 // NULL then the proto defaults to OBJ(OBJECT).  The new object
@@ -636,7 +652,7 @@
 // the thread_func function (see APR docs).
 // Example thread_func: void *main_thread(apr_thread_t *handle, void *argv);
 // The handle parameter is used for this_thread:  register_thread(handle);
-obj_p register_thread(apr_thread_t *this_thread);
+obj_p register_thread(isp ist, apr_thread_t *this_thread);
 
 //****************** HIGHER LEVEL OBJECT ACCESS ROUTINES ************************
 
@@ -862,11 +878,25 @@
 // See the routine read_unlock_write_lock in object.c.
 // Note: If object has immutable 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);
+// Note: If read or write lock returns TRUE, then that means there was an error
+// and the lock failed because either the caller did not have the permission rights
+// for the operation or a write attempt was made on an immutable object or a write
+// attempt was made on an object already read locked by the caller.
+// When an error is returned, the ist also contains an exception.
+int  read_lock    (isp ist, obj_p obj);
 void read_unlock  (isp ist, obj_p obj);	
-void write_lock   (isp ist, obj_p obj);		
+int  write_lock   (isp ist, obj_p obj);		
 void write_unlock (isp ist, obj_p obj);	
 
+// XXX_LOCK_YYY:  These macros read or write lock and check for errors
+#define if_rdlock(obj)	 if (read_lock(ist, obj)) 
+#define rdlock_brk(obj)	 if (read_lock(ist, obj)) break
+#define rdlock_rtrn(obj) if (read_lock(ist, obj)) return
+#define if_wrlock(obj)	 if (write_lock(ist, obj)) 
+#define wrlock_brk(obj)	 if (write_lock(ist, obj)) break
+#define wrlock_rtrn(obj) if (write_lock(ist, obj)) return
+
+
 //************************** UNMUTABLE BIT ***********************************
 // Each object has a bit called immutable.  This bit is effectively a write-protect
 // bit for the object.  When set the object cannot be modified.  Any attempt

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/include/prothon/prothon_dll.h	2004-04-06 02:35:08 UTC (rev 289)
@@ -63,7 +63,7 @@
 #endif
 
 typedef struct {
-	isp			(*get_ist)();
+	isp			(*get_ist)(access_t access);
 	obj_p		(*get_attr)(isp ist, obj_p obj, obj_p key);
 	void		(*set_attr)(isp ist, obj_p object, obj_p key, obj_p value);
 	int			(*del_attr)(isp ist, obj_p obj, obj_p key);
@@ -109,9 +109,9 @@
 	obj_p* 				OBJ_;
 	sym_id_entry_t* 	sym_id_table;
 
-	void		   (*read_lock)(isp ist, obj_p obj);	
+	int		   (*read_lock)(isp ist, obj_p obj);	
 	void		 (*read_unlock)(isp ist, obj_p obj);	
-	void		  (*write_lock)(isp ist, obj_p obj);		
+	int		  (*write_lock)(isp ist, obj_p obj);		
 	void		(*write_unlock)(isp ist, obj_p obj);
 
 	void		    (*del_lock)(obj_p obj);		
@@ -149,7 +149,7 @@
 PR_DECLARE_EXPORT void name##_dll_entry(pr_services_t* srvcs)	\
 {								\
 	services = srvcs;					\
-	ist = get_ist();					\
+	ist = get_ist(ACC_SYSTEM);					\
 	name##_module_install();				\
 }								\
 static void name##_module_install(void)

Modified: trunk/pr/test.pr
===================================================================
--- trunk/pr/test.pr	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/pr/test.pr	2004-04-06 02:35:08 UTC (rev 289)
@@ -1,5 +1,7 @@
 #!/usr/bin/env prothon
 
+print "hello world"
+
 p = Object()
 with p:
 	def .__init__(x=1):

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/builtins-core.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -321,37 +321,39 @@
 	set_attr(ist, OBJ(OBJECT), sym(ist, "Exception"), Exception_OBJ);
 
 	/* Other exception objects dependent on this one */
-	OBJ(INTERNAL_EXC)	= new_object(Exception_OBJ);
-	OBJ(PARSEERROR_EXC)	= new_object(Exception_OBJ);
+	OBJ(INTERNAL_EXC)		= new_object(Exception_OBJ);
+	OBJ(PARSEERROR_EXC)		= new_object(Exception_OBJ);
 	OBJ(INTERPRETER_EXC)	= new_object(Exception_OBJ);
-	OBJ(ASSERTION_EXC)	= new_object(Exception_OBJ);
-	OBJ(NAME_EXC)		= new_object(Exception_OBJ);
-	OBJ(INDEX_EXC)		= new_object(Exception_OBJ);
+	OBJ(ASSERTION_EXC)		= new_object(Exception_OBJ);
+	OBJ(NAME_EXC)			= new_object(Exception_OBJ);
+	OBJ(INDEX_EXC)			= new_object(Exception_OBJ);
 	OBJ(FUNCNOTFOUND_EXC)	= new_object(Exception_OBJ);
-	OBJ(TYPE_EXC)		= new_object(Exception_OBJ);
-	OBJ(MUTABLE_EXC)	= new_object(Exception_OBJ);
-	OBJ(DIVIDEZERO_EXC)	= new_object(Exception_OBJ);
+	OBJ(TYPE_EXC)			= new_object(Exception_OBJ);
+	OBJ(MUTABLE_EXC)		= new_object(Exception_OBJ);
+	OBJ(DIVIDEZERO_EXC)		= new_object(Exception_OBJ);
 	OBJ(OUTOFMEMORY_EXC)	= new_object(Exception_OBJ);
-	OBJ(IOEXCEPTION)	= new_object(Exception_OBJ);
+	OBJ(IOEXCEPTION)		= new_object(Exception_OBJ);
 	OBJ(FILENOTFOUND_EXC)	= new_object(OBJ(IOEXCEPTION));
 	OBJ(STOP_ITERATION_EXC)	= new_object(Exception_OBJ);
-	OBJ(LOCK_EXC)		= new_object(Exception_OBJ);
+	OBJ(LOCK_EXC)			= new_object(Exception_OBJ);
+	OBJ(PERMISSION_EXC)		= new_object(Exception_OBJ);
 
 	/* And their doc entries */
 	add_doc_to_obj(ist, OBJ(INTERNAL_EXC),		"Internal Prothon Error");
 	add_doc_to_obj(ist, OBJ(PARSEERROR_EXC),	"Parse Error");
 	add_doc_to_obj(ist, OBJ(INTERPRETER_EXC),	"Program Error");
 	add_doc_to_obj(ist, OBJ(ASSERTION_EXC),		"Assertion Error");
-	add_doc_to_obj(ist, OBJ(NAME_EXC),		"Name Error");
-	add_doc_to_obj(ist, OBJ(INDEX_EXC),		"Index Error");
-	add_doc_to_obj(ist, OBJ(TYPE_EXC),		"Type Error");
+	add_doc_to_obj(ist, OBJ(NAME_EXC),			"Name Error");
+	add_doc_to_obj(ist, OBJ(INDEX_EXC),			"Index Error");
+	add_doc_to_obj(ist, OBJ(TYPE_EXC),			"Type Error");
 	add_doc_to_obj(ist, OBJ(MUTABLE_EXC),		"Mutable Error");
 	add_doc_to_obj(ist, OBJ(DIVIDEZERO_EXC),	"Divide by zero error");
 	add_doc_to_obj(ist, OBJ(OUTOFMEMORY_EXC),	"Out Of Memory Error");
 	add_doc_to_obj(ist, OBJ(IOEXCEPTION),		"IO Error");
-	add_doc_to_obj(ist, OBJ(FILENOTFOUND_EXC),	"File Not Found");
+	add_doc_to_obj(ist, OBJ(FILENOTFOUND_EXC),		"File Not Found");
 	add_doc_to_obj(ist, OBJ(STOP_ITERATION_EXC),	"End Of Generated Sequence (no error)");
-	add_doc_to_obj(ist, OBJ(LOCK_EXC),		"Locking Error");
+	add_doc_to_obj(ist, OBJ(LOCK_EXC),				"Locking Error");
+	add_doc_to_obj(ist, OBJ(PERMISSION_EXC),		"Permission Error");
 }
 
 DEF(Exception, __init__,  FORM_STAR_PARAM) {

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/builtins-int.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -87,9 +87,10 @@
 	OBJ(ZERO_INT)		= new_int_obj(0);
 	OBJ(MAX_INT)		= new_int_obj(MAX_INT_VAL);
 	OBJ(LONG_PROTO)		= new_string_obj("0");
+	clr_immutable(OBJ(LONG_PROTO));
+	add_doc_to_obj(ist, OBJ(LONG_PROTO),	"Long integer number object prototype");
+	set_immutable(OBJ(LONG_PROTO));
 
-	add_doc_to_obj(ist, OBJ(LONG_PROTO),	"Long integer number object prototype");
-	
 	Int_OBJ->data_type    = OBJ_TYPE_IMMDATA;
 	Int_OBJ->imm_data_len = IMMEDIATE_DATA_LEN;
 	Int_OBJ->data.i64     = 0;
@@ -323,7 +324,7 @@
 		if (limit) {
 			read_unlock(ist, self);
 			del_attr(ist, self, SYM_LIMIT);
-			read_lock(ist, self);
+			rdlock_rtrn(self) NULL;
 		}
 		raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
 		return NULL;

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/interp.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -74,11 +74,12 @@
 
 static int prt_code_line(exec_frame_t* frame, code* code, int pc, FILE* fout);
 
-isp get_ist() {
+isp get_ist(access_t access) {
 	isp ist = pr_malloc(sizeof(interp_state_t));
 	ist->frame = NULL;
 	ist->exception_obj = 0;
 	ist->lock_stack = new_clist(20);
+	ist->access = access;
 	return ist;
 }
 
@@ -528,20 +529,30 @@
 
 #define MIN_OBJ ((obj_p) 10)
 
-#define pre_call_lock(slf, plist)							\
-	read_lock(ist, slf);											\
-	if (plist)												\
-		for(i=0; i < clist_len(plist); i++) {				\
-			obj_p p = clist_item(plist, i);					\
-			if (p > MIN_OBJ && p != (slf)) {read_lock(ist, p);}	\
-		}
+#define pre_call_lock(slf, plist)					\
+	read_lock(ist, slf);							\
+	if (!intrp_exobj && plist) {					\
+		for(i=0; i < clist_len(plist); i++) {		\
+			obj_p p = clist_item(plist, i);			\
+			if (p > MIN_OBJ && p != (slf))			\
+				rdlock_brk(p);						\
+		}											\
+		if (intrp_exobj) {							\
+			for (i--; i >= 0; i--) {				\
+				obj_p p = clist_item(plist, i);		\
+				if (p > MIN_OBJ && p != (slf))		\
+					read_unlock(ist, p);			\
+			}										\
+		}											\
+	}
 
-#define post_call_unlock(slf, plist)						\
-	read_unlock(ist, slf);										\
-	if (plist)												\
-		for(i=0; i < clist_len(plist); i++) {				\
-			obj_p p = clist_item(plist, i);					\
-			if (p > MIN_OBJ && p != (slf)) {read_unlock(ist, p);}\
+#define post_call_unlock(slf, plist)				\
+	read_unlock(ist, slf);							\
+	if (plist)										\
+		for(i=0; i < clist_len(plist); i++) {		\
+			obj_p p = clist_item(plist, i);			\
+			if (p > MIN_OBJ && p != (slf))			\
+				read_unlock(ist, p);				\
 		}
 
 //******************************** exec_loop **********************************
@@ -853,7 +864,7 @@
 				if ((func_obj = fr_stack[0])->data_type == OBJ_TYPE_FUNCPTR){
 					obj_p res;
 					clist_p plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+1);
-					pre_call_lock(frame->locals, plist);
+					pre_call_lock(frame->locals, plist); if (intrp_exobj) break;
 					res = ((pr_func*)(func_obj->data.ptr))
 								(ist, frame->locals, 
 								(plist ? clist_len(plist) : 0), 
@@ -939,7 +950,7 @@
 					obj_p res, slf = fr_stack[fr_sp];
 					clist_p plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
 					if (intrp_exobj) break;
-					pre_call_lock(slf, plist);
+					pre_call_lock(slf, plist);  if (intrp_exobj) break;
 					res = ((pr_func*)(func_obj->data.ptr))
 								(ist, slf, 
 								(plist ? clist_len(plist) : 0), 
@@ -1194,7 +1205,7 @@
 		int i;
 		obj_p res;
 		clist_p plist = get_func_params( ist, func_obj, parm_cnt, lbl_val_arr);
-		pre_call_lock(self, plist);
+		pre_call_lock(self, plist); if (intrp_exobj) return NULL;
 		res = ((pr_func*)(func_obj->data.ptr)) 
 								(ist, self, (plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL), dyn_locals);
@@ -1382,7 +1393,7 @@
 
 //******************************** main_thread ***********************************
 void *main_thread(apr_thread_t *handle, void *argv){
-	isp ist = get_ist();
+	isp ist = get_ist(ACC_USER2);
 	int main_index=1;
 	obj_p main_sym, module, thread_obj;
 	pr_thread_p thread_p;
@@ -1392,7 +1403,7 @@
 	printf("Starting a main thread\n");
 #endif
 
-	thread_obj = register_thread(handle);
+	thread_obj = register_thread(ist, handle);
 	thread_p = thread_obj->data.ptr;
 
 	pr_lock(&start_main_lock);
@@ -1421,7 +1432,7 @@
 	SetThreadName(symch(ist, main_sym));
 #endif
 
-	ist = get_ist();
+	ist = get_ist(ACC_USER2);
 	set_attr(ist, module, sym(ist, "Argv"), (obj_p) argv);
 	if (!load_module(ist, main_sym, NULL, NULL, NULL, filename, 
 									": a top-level module", module, NULL)) {

Modified: trunk/src/interp.h
===================================================================
--- trunk/src/interp.h	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/interp.h	2004-04-06 02:35:08 UTC (rev 289)
@@ -62,7 +62,7 @@
 
 #include <apr_thread_proc.h>
 
-isp get_ist();
+isp get_ist(access_t access);
 obj_p check_exceptions(isp ist);
 
 extern i32_t main_threads_started;

Modified: trunk/src/lock.c
===================================================================
--- trunk/src/lock.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/lock.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -90,6 +90,11 @@
 //********************************* read_lock_try *****************************
 int read_lock_try(isp ist, obj_p obj) {
 	if (!lock((obj)->wrlock)) return FALSE;
+	if (ist->access < obj->rd_access) {
+		raise_exception(ist, OBJ(PERMISSION_EXC), "read-try permission exception");
+		free_wrlock(obj);
+		return FALSE;
+	}
 	if (obj->immutable) {
 		free_wrlock(obj);
 		return TRUE;
@@ -106,11 +111,16 @@
 }
 
 //********************************* read_lock *********************************
-void read_lock(isp ist, obj_p obj) {
+int read_lock(isp ist, obj_p obj) {
 	get_wrlock(obj, NO_WAIT);
+	if (ist->access < obj->rd_access) {
+		raise_exception(ist, OBJ(PERMISSION_EXC), "read permission exception");
+		free_wrlock(obj);
+		return TRUE;
+	}
 	if (obj->immutable) {
 		free_wrlock(obj);
-		return;
+		return FALSE;
 	}
 	if (obj->wrlock_req_cnt && !clist_in(lockstack, obj)) { 
 		while(obj->wrlock_req_cnt) {
@@ -122,7 +132,7 @@
 	obj->rdlock_cnt++;
 	obj->state = OBJ_STATE_NEW_OR_MARKED;
 	free_wrlock(obj);
-	return;
+	return FALSE;
 }
 
 //********************************* read_unlock *******************************
@@ -147,6 +157,11 @@
 //********************************* write_lock_try ****************************
 int write_lock_try(isp ist, obj_p obj) {
 	if (!lock((obj)->wrlock)) return FALSE;
+	if (ist->access < obj->wr_access) {
+		raise_exception(ist, OBJ(PERMISSION_EXC), "write-try permission exception");
+		free_wrlock(obj);
+		return FALSE;
+	}
 	if (obj->immutable) {
 		raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an immutable object");
 		free_wrlock(obj);
@@ -161,19 +176,25 @@
 }
 
 //********************************* write_lock ********************************
-void write_lock(isp ist, obj_p obj) {
+int write_lock(isp ist, obj_p obj) {
 	int sav_cnt = 0;
 	get_wrlock(obj, NO_WAIT);
+	if (ist->access < obj->wr_access) {
+		raise_exception(ist, OBJ(PERMISSION_EXC), "write permission exception");
+		free_wrlock(obj);
+		return TRUE;
+	}
 	if (obj->immutable) {
 		raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an immutable object");
-		// something should be done to stop code from actually modifying object XXX
 		free_wrlock(obj);
-		return;
+		return TRUE;
 	}
 	if(obj->rdlock_cnt) {
 		if(clist_in(lockstack, obj)) {
-			raise_exception(ist, OBJ(LOCK_EXC), "write_lock performed on a read_locked object");
+			raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on a read_locked object");
 			obj->rdlock_cnt -= sav_cnt = clist_in_cnt(lockstack, obj);
+			free_wrlock(obj);
+			return TRUE;
 		}
 		apr_thread_mutex_lock(write_mutex);
 		while (obj->rdlock_cnt) {
@@ -187,6 +208,7 @@
 		obj->rdlock_cnt += sav_cnt;
 	}
 	obj->long_wrlock = TRUE;
+	return FALSE;
 }
 
 //********************************* write_unlock ******************************

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/main.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -93,10 +93,11 @@
 /* New threads must call this first thing, it will release the
  * thread_registry_lock so that other threads can start. 
  * Returns the matching thread object */
-obj_p register_thread(apr_thread_t *this_thread)
+obj_p register_thread(isp ist, apr_thread_t *this_thread)
 {
 	obj_p res = new_thread_object;
 	pr_thread_p thread_ptr    = res->data.ptr;
+	thread_ptr->ist           = ist;
 	thread_ptr->apr_os_thread = apr_os_thread_current();
 	thread_ptr->apr_thread    = this_thread;
 	clist_append(thread_registry, res);
@@ -201,7 +202,7 @@
 	}
 
 	/* Now that apr is ready, on to our stuff */
-	ist = get_ist();
+	ist = get_ist(ACC_SYSTEM);
 
 	yydebug = 0;
 

Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/memory_mgr.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -109,12 +109,12 @@
 
 //********************************* mem_mgr_thread ******************************
 void *mem_mgr_thread(apr_thread_t *handle, void *dummy) {
-	isp ist = get_ist();
+	isp ist = get_ist(ACC_SYSTEM);
 	obj_p mm_obj_list = new_list_obj(100);
 	obj_p mm_obj_act_param[2]; 
 	int      last_obj_del_count = 0,      last_obj_count = 0;     
 
-	register_thread(handle);
+	register_thread(ist, handle);
 
 	mm_obj_act_param[0] = NULL; 
 	mm_obj_act_param[1] = mm_obj_list;

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/object.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -220,6 +220,8 @@
 	obj_p obj = pr_malloc(sizeof(obj_t));
 	memset(obj, 0, sizeof(obj_t));
 	if (!proto) proto = OBJ(OBJECT);
+	//obj->rd_access = ACC_SYSTEM;
+	//obj->wr_access = ACC_SYSTEM;
 	obj->attr_proto.proto = proto;
 	lock_init(obj->wrlock);
 	obj->del_locked = TRUE;
@@ -317,7 +319,7 @@
 
 //********************************* get_attr *******************************
 obj_p get_attr(isp ist, obj_p obj, obj_p key) {
-	read_lock(ist, obj);
+	rdlock_rtrn(obj) NULL;
 	if (obj->has_attrs){
 		attr_p ptr, attrs = obj->attr_proto.attrs;
 		attr_key_t i, akey, tgt = key->data.key;
@@ -496,7 +498,7 @@
 //********************************* proto_len **********************************
 int proto_len(isp ist, obj_p obj){
 	int res;
-	read_lock(ist, obj);
+	rdlock_rtrn(obj) 0;
 	if (!obj->has_attrs) {
 		read_unlock(ist, obj);
 		return 1;
@@ -509,7 +511,7 @@
 //********************************* proto_item *********************************
 obj_p proto_item(isp ist, obj_p obj, int i){
 	obj_p res;
-	read_lock(ist, obj);
+	rdlock_rtrn(obj) NULL;
 	if (!obj->has_attrs)
 		res = obj->attr_proto.proto;
 	else
@@ -523,8 +525,8 @@
 	i32_t i, j, k = 0, len;
 	obj_p proto, list_obj;
 	clist_t *pao_list;
+	rdlock_rtrn(obj) NULL;
 	pao_list = new_clist(10);
-	read_lock(ist, obj);
 	ins_clist(pao_list, obj, 0);
 	for (i=0; i < clist_len(pao_list); i++) {
 		obj = clist_item(pao_list,i);
@@ -532,7 +534,11 @@
 		for(j=0; j < len; j++) {
 			proto = proto_item(ist, obj, j);
 			if (proto != OBJ(OBJECT)) {
-				read_lock(ist, proto);
+				if_rdlock(proto){
+					clist_read_unlock(ist, pao_list);
+					free_clist(pao_list);
+					return NULL;
+				}
 				clist_append(pao_list, proto);
 			}
 		}
@@ -543,7 +549,11 @@
 			return NULL;
 		}
 	}
-	read_lock(ist, OBJ(OBJECT));
+	if_rdlock(OBJ(OBJECT)){
+		clist_read_unlock(ist, pao_list);
+		free_clist(pao_list);
+		return NULL;
+	}
 	clist_append(pao_list, OBJ(OBJECT));
 	for (j = clist_len(pao_list)-1; j > 0; j--)
 		if ((proto = clist_item(pao_list, j)))
@@ -566,7 +576,7 @@
 	i32_t i, j, len;
 	obj_p proto;
 	clist_t *pao_list;
-	read_lock(ist, obj);
+	rdlock_rtrn(obj) 0;
 
 	if ( (!obj->has_attrs && obj->attr_proto.proto == obj_proto) ||
 		 obj_proto == OBJ(OBJECT) ) {
@@ -582,7 +592,11 @@
 			proto = proto_item(ist, obj, j);
 			if (proto != OBJ(OBJECT)) {
 				if (proto == obj_proto) goto end_true;
-				read_lock(ist, proto);
+				if_rdlock(proto){
+					clist_read_unlock(ist, pao_list);
+					free_clist(pao_list);
+					return FALSE;
+				}
 				clist_append(pao_list, proto);
 			}
 		}
@@ -610,7 +624,7 @@
 	clist_t *pao_list;
 	if (proto_pp) *proto_pp = NULL;
 	while (TRUE){
-		read_lock(ist, obj);
+		rdlock_rtrn(obj) NULL;
 		if( (res = get_attr(ist, obj, key)) || obj == OBJ(OBJECT) ) {
 			if (!second) {
 				read_unlock(ist, obj);
@@ -626,18 +640,30 @@
 		pao_list = new_clist(len*2+4);
 		for (i=0; i < len; i++)
 			if ((proto = proto_item(ist, obj, i)) != OBJ(OBJECT)) {
-				read_lock(ist, proto);
+				if_rdlock(proto){
+					clist_read_unlock(ist, pao_list);
+					free_clist(pao_list);
+					return NULL;
+				}
 				clist_append(pao_list, proto);
 			}					
 		read_unlock(ist, obj);
 		for (i=0; i < clist_len(pao_list); i++){
 			obj = clist_item(pao_list, i);
-			read_lock(ist, obj);
+			if_rdlock(obj){
+				clist_read_unlock(ist, pao_list);
+				free_clist(pao_list);
+				return NULL;
+			}
 			len = proto_len(ist, obj);
 			for(j=0; j < len; j++) {
 				proto = proto_item(ist, obj, j);
 				if (proto != OBJ(OBJECT)) {
-					read_lock(ist, proto);
+					if_rdlock(proto){
+						clist_read_unlock(ist, pao_list);
+						free_clist(pao_list);
+						return NULL;
+					}
 					clist_append(pao_list, proto);
 				}
 			}
@@ -650,7 +676,11 @@
 			}
 			read_unlock(ist, obj);
 		}
-		read_lock(ist, OBJ(OBJECT));
+		if_rdlock(OBJ(OBJECT)){
+			clist_read_unlock(ist, pao_list);
+			free_clist(pao_list);
+			return NULL;
+		}
 		clist_append(pao_list, OBJ(OBJECT));
 		for (j = clist_len(pao_list)-1; j > 0; j--)
 			if ((proto = clist_item(pao_list,j)))
@@ -944,7 +974,7 @@
 	obj_p res;
 	size_t llen, size;
 	list_p list_ptr;
-	read_lock(ist, list_obj);
+	rdlock_rtrn(list_obj) NULL;
 	llen = listlen(list_obj);
 	size = list_sizeof(llen);
 	res = clone_object(list_obj);
@@ -960,7 +990,7 @@
 //********************************* list_len **********************************
 size_t list_len(isp ist, obj_p list_obj){
 	size_t len;
-	read_lock(ist, list_obj);
+	rdlock_rtrn(list_obj) 0;
 	len = listlen(list_obj);
 	read_unlock(ist, list_obj);
 	return len;
@@ -976,7 +1006,7 @@
 //********************************* list_item *********************************
 obj_p list_item(isp ist, obj_p list_obj, int i){
 	obj_p res;
-	read_lock(ist, list_obj);
+	rdlock_rtrn(list_obj) NULL;
 	res = listitem(list_obj, i);
 	read_unlock(ist, list_obj);
 	return res;
@@ -1101,7 +1131,7 @@
 //********************************* dict_len **********************************
 size_t dict_len(isp ist, obj_p dict_obj){
 	size_t res;
-	read_lock(ist, dict_obj);
+	rdlock_rtrn(dict_obj) 0;
 	res = dictlen(dict_d(dict_obj));
 	read_unlock(ist, dict_obj);
 	return res;
@@ -1119,7 +1149,7 @@
 	obj_p key, res, rp[2];
 	dict_p dict, dp;
 	rp[0]=0; rp[1]=key_in;
-	read_lock(ist, dict_obj);
+	rdlock_rtrn(dict_obj) NULL;
 	hash_in = hash_value(call_func(ist, key_in, SYM(__HASH__), 0, NULL, NULL));
 	dict_rd_chk();
 	dict = (dict_p) obj_data_p(dict_obj);
@@ -1142,7 +1172,7 @@
 	size_t i, size, len, cnt=0;
 	obj_p list_obj;
 	dict_p dict, dp;
-	read_lock(ist, dict_obj);
+	rdlock_rtrn(dict_obj) NULL;
 	dict = dict_d(dict_obj);
 	size = dictsize(dict);
 	len  = dictlen(dict);
@@ -1199,7 +1229,7 @@
 char* keych(isp ist, attr_key_t key) {
 	int i, len;
 	char* res;
-	read_lock(ist, OBJ(SYMBOLS));
+	rdlock_rtrn(OBJ(SYMBOLS)) NULL;
 	len = (int) list_len(ist, OBJ(SYMBOLS));
 	for(i=0; i < len; i++)
 		if (list_item(ist, OBJ(SYMBOLS),i)->data.key == key)

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/object.h	2004-04-06 02:35:08 UTC (rev 289)
@@ -147,7 +147,7 @@
 obj_p arginit(isp its, int argc, char* argv[]);
 void sysinit(isp ist, char* prog_path, obj_p argv_obj);
 
-isp get_ist(void);
+isp get_ist(access_t access);
 
 obj_p load_sys_module(isp ist, char* prog_path, obj_p argv_obj);
 #define get_sys_path_list()  \

Modified: trunk/src/sys.c
===================================================================
--- trunk/src/sys.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/sys.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -245,7 +245,7 @@
 				if (!(*p) || *p == '#') continue;
 				if (!strncmp(p, "import ", 7)) {
 					char doc[300];
-					isp ist = get_ist();
+					isp ist = get_ist(ACC_USER2);
 					apr_snprintf(modname, sizeof(modname), "PthMod%d", ++modname_cnt);
 					apr_snprintf(doc, sizeof(doc), ": a module loaded by %s",
 							file_info.name);

Modified: trunk/src/thread.c
===================================================================
--- trunk/src/thread.c	2004-04-05 18:55:12 UTC (rev 288)
+++ trunk/src/thread.c	2004-04-06 02:35:08 UTC (rev 289)
@@ -60,17 +60,23 @@
 #include <time.h>
 
 #include <apr_time.h>
+#include <apr.h>
+#include <apr_thread_proc.h>
+#include <apr_strings.h>
+#include <apr_dso.h>
+#include <string.h>
 
+
 #ifdef DEBUG_THREADS
 
 int torture_scan_thread_count = 0;
 
 void *torture_scan_thread(apr_thread_t *handle, void* thread_number_ptr) {
-	isp ist = get_ist();
+	isp ist = get_ist(ACC_SYSTEM);
 	obj_p obj = NULL;
 	int scan_num = *((int*)thread_number_ptr);
 
-	register_thread(handle);
+	register_thread(ist, handle);
 
 	torture_scan_thread_count++;
 	srand( (unsigned)time( 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.