r9p

git clone git://oldgit.suckless.org/r9p/
Log | Files | Refs

thread.rb (2072B)


      1 # Copyright (C) 2007 Kris Maglione
      2 # See PERMISSIONS
      3 
      4 begin
      5 	require 'thread'
      6 rescue
      7 	# Threading is not necessary for most functions
      8 	module Stub
      9 		class <<self
     10 			def nops(*arg)
     11 				arg.each { |s|
     12 					module_eval <<-"end_eval"
     13 						alias #{s.id2name} nop
     14 					end_eval
     15 				}
     16 			end
     17 			def error(name, *arg)
     18 				first = arg.shift
     19 				module_eval <<-"end_eval"
     20 					def #{first.id2name}(*arg)
     21 						throw #{name.inspect}
     22 					end
     23 				end_eval
     24 				arg.each { |s| module_eval "alias #{s.id2name} #{first.id2name}" }
     25 			end
     26 		end
     27 		def nop(*arg)
     28 			puts "In nop!"
     29 			if block_given?
     30 				yield
     31 			end
     32 		end
     33 	end
     34 	class Thread
     35 		include Stub
     36 		@@dummy = new
     37 		def current
     38 			@@dummy
     39 		end
     40 		Stub.error 'Threading not implemented', :initialize, :wakeup
     41 		Stub.nops :exclusive, :critical, :critical=
     42 
     43 		class <<self
     44 			Stub.error 'Threading not implemented', :fork, :start, :stop
     45 		end
     46 	end
     47 
     48 	# Locking is not necessary without threading
     49 	class Mutex
     50 		include Stub
     51 		Stub.nops :lock, :unlock, :synchronize, :initialize, :locked?
     52 		def locked?
     53 			false
     54 		end
     55 	end
     56 end
     57 
     58 module R9P
     59 	module Qlock
     60 		def qlinit
     61 			@ql_queue = []
     62 			@ql_locked = nil
     63 		end
     64 
     65 		def qlock
     66 			cr = Thread.critical
     67 			while (Thread.critical = true; @ql_locked != nil && @ql_locked != Thread.current)
     68 				unless @ql_queue.include?(Thread.current)
     69 					@ql_queue.push Thread.current
     70 				end
     71 				Thread.stop
     72 			end
     73 			@ql_locked = Thread.current
     74 			Thread.critical = cr
     75 			self
     76 		end
     77 		def qunlock
     78 			if @ql_locked != Thread.current
     79 				raise
     80 			end
     81 			cr = Thread.critical
     82 			Thread.critical = true
     83 			thr = @ql_locked = @ql_queue.shift
     84 			@ql_locked.wakeup if @ql_locked
     85 			if block_given?
     86 				yield
     87 			end
     88 		ensure
     89 			Thread.critical = cr
     90 			thr.run if thr
     91 		end
     92 		def qsync
     93 			qlock
     94 			yield
     95 		ensure
     96 			qunlock
     97 		end
     98 		def qlocked?
     99 			@ql_locked ? true : false
    100 		end
    101 	end
    102 	module Rendez
    103 		def sleep
    104 			@thread = Thread.current
    105 			@lock.qunlock {
    106 				Thread.stop
    107 			}
    108 			@lock.qlock
    109 			@thread = nil if @thread == Thread.current
    110 		end
    111 		def wakeup
    112 			if @thread
    113 				@thread.wakeup
    114 			end
    115 		end
    116 	end
    117 end