Factor common TimeSpec methods into module.
This commit is contained in:
parent
71aa552213
commit
ffe1298731
|
@ -83,10 +83,6 @@ module ProcessShared
|
|||
sem_wait(@sem)
|
||||
end
|
||||
|
||||
NS_PER_S = 1e9
|
||||
US_PER_NS = 1000
|
||||
TV_NSEC_MAX = (NS_PER_S - 1)
|
||||
|
||||
# Decrement the value of the semaphore if it can be done
|
||||
# immediately (i.e. if it was non-zero). Otherwise, wait up to
|
||||
# +timeout+ seconds until another process increments via {#post}.
|
||||
|
@ -100,24 +96,9 @@ module ProcessShared
|
|||
def try_wait(timeout = nil)
|
||||
if timeout
|
||||
now = TimeVal.new
|
||||
abs_timeout = TimeSpec.new
|
||||
|
||||
LibC.gettimeofday(now, nil)
|
||||
|
||||
abs_timeout[:tv_sec] = now[:tv_sec];
|
||||
abs_timeout[:tv_nsec] = now[:tv_usec] * US_PER_NS
|
||||
|
||||
# add timeout in seconds to abs_timeout; careful with rounding
|
||||
sec = timeout.floor
|
||||
nsec = ((timeout - sec) * NS_PER_S).floor
|
||||
|
||||
abs_timeout[:tv_sec] += sec
|
||||
abs_timeout[:tv_nsec] += nsec
|
||||
while abs_timeout[:tv_nsec] > TV_NSEC_MAX
|
||||
abs_timeout[:tv_sec] += 1
|
||||
abs_timeout[:tv_nsec] -= NS_PER_S
|
||||
end
|
||||
|
||||
abs_timeout = now.to_time_spec
|
||||
abs_timeout.add_seconds!(timeout)
|
||||
sem_timedwait(@sem, abs_timeout)
|
||||
else
|
||||
sem_trywait(@sem)
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
require 'ffi'
|
||||
require 'process_shared/time_spec'
|
||||
|
||||
module ProcessShared
|
||||
module Posix
|
||||
class TimeSpec < FFI::Struct
|
||||
include ProcessShared::TimeSpec
|
||||
|
||||
layout(:tv_sec, :time_t,
|
||||
:tv_nsec, :long)
|
||||
end
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
require 'ffi'
|
||||
|
||||
require 'process_shared/posix/time_spec'
|
||||
|
||||
module ProcessShared
|
||||
module Posix
|
||||
class TimeVal < FFI::Struct
|
||||
US_PER_NS = 1000
|
||||
|
||||
layout(:tv_sec, :time_t,
|
||||
:tv_usec, :suseconds_t)
|
||||
|
||||
def to_time_spec
|
||||
ts = TimeSpec.new
|
||||
|
||||
ts[:tv_sec] = self[:tv_sec];
|
||||
ts[:tv_nsec] = self[:tv_usec] * US_PER_NS
|
||||
|
||||
ts
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
module ProcessShared
|
||||
module TimeSpec
|
||||
NS_PER_S = 1e9
|
||||
US_PER_NS = 1000
|
||||
TV_NSEC_MAX = (NS_PER_S - 1)
|
||||
|
||||
# Assuming self responds to setting the value of [:tv_sec] and
|
||||
# [:tv_nsec], add +secs+ to the time spec.
|
||||
def add_seconds!(float_sec)
|
||||
# add timeout in seconds to abs_timeout; careful with rounding
|
||||
sec = float_sec.floor
|
||||
nsec = ((float_sec - sec) * NS_PER_S).floor
|
||||
|
||||
self[:tv_sec] += sec
|
||||
self[:tv_nsec] += nsec
|
||||
while self[:tv_nsec] > TV_NSEC_MAX
|
||||
self[:tv_sec] += 1
|
||||
self[:tv_nsec] -= NS_PER_S
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue