This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

semaphore unlock after timeout
#1
hi, 

is there a way i can i have this to unlock itself after the timeout period executed by the callback?

many thanks,

require('sem')

-- wait for 5 seconds max before executing callback
res1, res2 = sem.runlocked('eventlock', 5, function(lockres)
  -- lock acquired
  if lockres then
    return true, 'lock ok'
  -- failed to acquire lock
  else
    return nil, 'lock failed'
  end
end)

log(res1, res2)
Reply
#2
This is not safe because it leads to race conditions which semaphores prevent. Can you explain why do you need this? If your function can fail due to an error you should execute it using pcall().
Reply
#3
(06.01.2020, 15:18)admin Wrote: This is not safe because it leads to race conditions which semaphores prevent. Can you explain why do you need this? If your function can fail due to an error you should execute it using pcall().
Ok thanks, 

what i am trying to achieve is to have a event script, switch on a group, start a timer then, timeout and switch off a group (also block the resident script from running again while the timer is running ) 
the event script is triggered by an security alarm message which can happen quite fast (every time the pir is triggered, this is why i want to block the script from running if it has been triggered so i don't have multiple scripts running)

are you able to point me in the right direction. 

Many Thanks
Reply
#4
(06.01.2020, 20:55)benanderson_475 Wrote:
(06.01.2020, 15:18)admin Wrote: This is not safe because it leads to race conditions which semaphores prevent. Can you explain why do you need this? If your function can fail due to an error you should execute it using pcall().
Ok thanks, 

what i am trying to achieve is to have a event script, switch on a group, start a timer then, timeout and switch off a group (also block the resident script from running again while the timer is running ) 
the event script is triggered by an security alarm message which can happen quite fast (every time the pir is triggered, this is why i want to block the script from running if it has been triggered so i don't have multiple scripts running)

are you able to point me in the right direction. 

Many Thanks
Hi!
Perhaps my solution will be useful.
You must create a resident script
Code:
local my_tmr_table = storage.get('my_timers')
if my_tmr_table then
    for my_grp,tmr in pairs(my_tmr_table) do
       local my_grp_name = grp.alias(my_grp)
       if my_grp_name then
         if (os.time() - tmr[1]) > tmr[2] then
            grp.write(my_grp,0)
            my_tmr_table [my_grp_name] = nil
         end
        else
         my_grp = nil
        end
    end
end
storage.set('my_timers', my_tmr_table)
This resident script runs every second and load group objects with UNIX time when timer set (tmr[1]) and for which duration timer set (tmr[2]). If timer for specific group is run out, timer will be destroyed.
Also you need function to set timer
Code:
function my_timer (my_grp , on_t , dur)
   local my_tmr_table = storage.get('my_timers')
   if my_tmr_table then
   else
      my_tmr_table = {}
   end
   k = grp.alias(my_grp)
   my_tmr_table[k] = {on_t,dur}
   storage.set('my_timers',my_tmr_table)
end
Arguments is:
my_grp - group name
on_t      - UNIX time at timer setup
dur        - duration in seconds
Now you can make script for an group address like this
Code:
if event.getvalue()  then
   my_timer (event.dst , os.time() , 300)
end
In the example above, timer is set to 300 seconds.

Anton
Reply
#5
Hi Anton, 

Many thanks, this is what i am looking for. 
This works well.
Reply


Forum Jump: