added experimental code that implements singal callback in semaphore
This commit is contained in:
		| @ -60,12 +60,21 @@ class Semaphore(Object) | |||||||
| 	    ioHandle      := nil, | 	    ioHandle      := nil, | ||||||
| 	    ioMask        :=   0. | 	    ioMask        :=   0. | ||||||
|  |  | ||||||
|  | 	var (#get,#set) signalAction := nil. | ||||||
| 	var(#get,#set) _group := nil. | 	var(#get,#set) _group := nil. | ||||||
|  |  | ||||||
| 	## ================================================================== | 	## ================================================================== | ||||||
|  |  | ||||||
| 	method(#primitive) signal. | 	method(#primitive) signal. | ||||||
| 	method(#primitive) wait. | 	method(#primitive) _wait. | ||||||
|  |  | ||||||
|  | 	method wait | ||||||
|  | 	{ | ||||||
|  | 		| k | | ||||||
|  | 		k := self _wait. | ||||||
|  | 		if (self.signalAction notNil) { self.signalAction value: self }. | ||||||
|  | 		^k | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	## ================================================================== | 	## ================================================================== | ||||||
|  |  | ||||||
| @ -246,7 +255,15 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method(#primitive) wait. | 	method(#primitive) _wait. | ||||||
|  |  | ||||||
|  | 	method wait | ||||||
|  | 	{ | ||||||
|  | 		| r | | ||||||
|  | 		r := self wait. | ||||||
|  | 		if (r signalAction notNil) { r signalAction value: r }. | ||||||
|  | 		^r | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	method waitWithTimeout: seconds | 	method waitWithTimeout: seconds | ||||||
| 	{ | 	{ | ||||||
| @ -267,7 +284,8 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit | |||||||
|  |  | ||||||
| 		## if the internal semaphore has been signaled,  | 		## if the internal semaphore has been signaled,  | ||||||
| 		## arrange to return nil to indicate timeout. | 		## arrange to return nil to indicate timeout. | ||||||
| 		if (r == s) { r := nil }. | 		if (r == s) { r := nil } | ||||||
|  | 		elsif (r signalAction notNil) { r signalAction value: r }. | ||||||
|  |  | ||||||
| 		## nullify the membership | 		## nullify the membership | ||||||
| 		s _group: nil.  | 		s _group: nil.  | ||||||
|  | |||||||
| @ -7,8 +7,6 @@ | |||||||
|  |  | ||||||
| class MyObject(Object) | class MyObject(Object) | ||||||
| { | { | ||||||
| ## TODO: support import in extend?? |  | ||||||
|  |  | ||||||
| 	var(#class) a := 100. | 	var(#class) a := 100. | ||||||
|  |  | ||||||
| 	method(#class) proc1 | 	method(#class) proc1 | ||||||
| @ -36,7 +34,6 @@ class MyObject(Object) | |||||||
| 		sempq deleteAt: 50. | 		sempq deleteAt: 50. | ||||||
| 		sempq deleteAt: 100. | 		sempq deleteAt: 100. | ||||||
|  |  | ||||||
| 	 |  | ||||||
| 		a := -100. | 		a := -100. | ||||||
| 		[sempq size > 0] whileTrue: [ | 		[sempq size > 0] whileTrue: [ | ||||||
| 			| sem b | | 			| sem b | | ||||||
| @ -85,6 +82,27 @@ class MyObject(Object) | |||||||
| 		^%( v, p ) ## v must be 2000, p must be 6000 | 		^%( v, p ) ## v must be 2000, p must be 6000 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | (* | ||||||
|  | 	method(#class) test_sem_sig | ||||||
|  | 	{ | ||||||
|  | 		| s | | ||||||
|  | 		s := Semaphore new. | ||||||
|  | 		s signalAction: [:sem | 'SIGNAL ACTION............' dump. ]. | ||||||
|  | 		[ Processor sleepFor: 1. s signal ] fork. | ||||||
|  | 		s wait. | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method(#class) test_semgrp | ||||||
|  | 	{ | ||||||
|  | 		| sg | | ||||||
|  | 		sg := SemaphoreGroup new. | ||||||
|  | 		sg add: s1 withAction: []. | ||||||
|  | 		sg add: s2 withAction: []. | ||||||
|  | 		sg add: s3 withAction: []. | ||||||
|  | 		sg wait. | ||||||
|  | 	} | ||||||
|  | *) | ||||||
|  |  | ||||||
| 	method(#class) main | 	method(#class) main | ||||||
| 	{ | 	{ | ||||||
| 		| tc limit | | 		| tc limit | | ||||||
| @ -94,7 +112,9 @@ class MyObject(Object) | |||||||
| 			[ self proc1 == 100 ],  | 			[ self proc1 == 100 ],  | ||||||
| 			[ Processor sleepFor: 2.  self proc1 == 200 ], | 			[ Processor sleepFor: 2.  self proc1 == 200 ], | ||||||
| 			[ self test_semaphore_heap == true ], | 			[ self test_semaphore_heap == true ], | ||||||
| 			[ self test_mutex = #(2000 6000) ] | 			[ self test_mutex = #(2000 6000) ], | ||||||
|  | 			####[ self test_sem_sig ], | ||||||
|  | 			[ a == 300 ] | ||||||
| 		). | 		). | ||||||
|  |  | ||||||
| 		limit := tc size. | 		limit := tc size. | ||||||
| @ -105,5 +125,19 @@ class MyObject(Object) | |||||||
| 			System log(System.Log.INFO, idx asString, (if (tb value) { ' PASS' } else { ' FAIL' }), S'\n'). | 			System log(System.Log.INFO, idx asString, (if (tb value) { ' PASS' } else { ' FAIL' }), S'\n'). | ||||||
| 		]. | 		]. | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | (* | ||||||
|  | s1 := TcpSocket new. | ||||||
|  |  | ||||||
|  | s1 onEvent: #connected do: [ | ||||||
|  | 	s1 write: C'GET / HTTP/1.0\n\r'. | ||||||
|  | ]  | ||||||
|  | s1 onEvent: #written do: [ | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | s1 on: #read do: | ||||||
|  | s1 connectTo: '1.2.3.4:45'. | ||||||
|  |  | ||||||
|  | *) | ||||||
|  | |||||||
| @ -8,36 +8,7 @@ | |||||||
| ## MAIN | ## MAIN | ||||||
| ################################################################# | ################################################################# | ||||||
|  |  | ||||||
| ## TODO: use #define to define a class or use #class to define a class. | class MyObject(Object) | ||||||
| ##       use #extend to extend a class |  | ||||||
| ##       using #class for both feels confusing. |  | ||||||
|  |  | ||||||
| extend Apex |  | ||||||
| { |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| extend SmallInteger |  | ||||||
| { |  | ||||||
| 	method getTrue: anInteger |  | ||||||
| 	{ |  | ||||||
| 		^anInteger + 9999. |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	method inc |  | ||||||
| 	{ |  | ||||||
| 		^self + 1. |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| class TestObject(Object) |  | ||||||
| { |  | ||||||
| 	var(#class) Q, R. |  | ||||||
| 	var(#classinst) a1, a2. |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class MyObject(TestObject) |  | ||||||
| { | { | ||||||
| 	var(#classinst) t1, t2. | 	var(#classinst) t1, t2. | ||||||
|  |  | ||||||
|  | |||||||
| @ -4243,8 +4243,8 @@ static pf_t pftab[] = | |||||||
| 	{ "Process__terminate",                    { pf_process_terminate,                    0, 0 } }, | 	{ "Process__terminate",                    { pf_process_terminate,                    0, 0 } }, | ||||||
|  |  | ||||||
| 	{ "Semaphore_signal",                      { pf_semaphore_signal,                     0, 0 } }, | 	{ "Semaphore_signal",                      { pf_semaphore_signal,                     0, 0 } }, | ||||||
| 	{ "Semaphore_wait",                        { pf_semaphore_wait,                       0, 0 } }, | 	{ "Semaphore__wait",                       { pf_semaphore_wait,                       0, 0 } }, | ||||||
| 	{ "SemaphoreGroup_wait",                   { pf_semaphore_group_wait,                 0, 0 } }, | 	{ "SemaphoreGroup__wait",                  { pf_semaphore_group_wait,                 0, 0 } }, | ||||||
|  |  | ||||||
| 	{ "SmallInteger_asCharacter",              { pf_smooi_as_character,                   0, 0 } }, | 	{ "SmallInteger_asCharacter",              { pf_smooi_as_character,                   0, 0 } }, | ||||||
| 	{ "SmallInteger_asError",                  { pf_smooi_as_error,                       0, 0 } }, | 	{ "SmallInteger_asError",                  { pf_smooi_as_error,                       0, 0 } }, | ||||||
|  | |||||||
| @ -748,7 +748,7 @@ struct moo_context_t | |||||||
| typedef struct moo_process_t moo_process_t; | typedef struct moo_process_t moo_process_t; | ||||||
| typedef struct moo_process_t* moo_oop_process_t; | typedef struct moo_process_t* moo_oop_process_t; | ||||||
|  |  | ||||||
| #define MOO_SEMAPHORE_NAMED_INSTVARS 10 | #define MOO_SEMAPHORE_NAMED_INSTVARS 11 | ||||||
| typedef struct moo_semaphore_t moo_semaphore_t; | typedef struct moo_semaphore_t moo_semaphore_t; | ||||||
| typedef struct moo_semaphore_t* moo_oop_semaphore_t; | typedef struct moo_semaphore_t* moo_oop_semaphore_t; | ||||||
|  |  | ||||||
| @ -814,6 +814,7 @@ struct moo_semaphore_t | |||||||
| 	moo_oop_t io_handle; | 	moo_oop_t io_handle; | ||||||
| 	moo_oop_t io_mask; /* SmallInteger */ | 	moo_oop_t io_mask; /* SmallInteger */ | ||||||
|  |  | ||||||
|  | 	moo_oop_t signal_action; | ||||||
| 	moo_oop_semaphore_group_t group; /* nil or belonging semaphore group */ | 	moo_oop_semaphore_group_t group; /* nil or belonging semaphore group */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user