Welcome to mirror list, hosted at ThFree Co, Russian Federation.

safe.lua - github.com/torch/threads-ffi.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f23354bea31f0ba9d18c9885c1fec4292ddbe6f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
-- utility for lua 5.2
local setfenv = setfenv or
   function(fn, env)
      local i = 1
      while true do
         local name = debug.getupvalue(fn, i)
         if name == "_ENV" then
            debug.upvaluejoin(fn, i, (function()
                                         return env
                                      end), 1)
            break
         elseif not name then
            break
         end
         i = i + 1
      end
      return fn
   end

local function newproxygc(func)
   local proxy
   if newproxy then -- 5.1
      proxy = newproxy(true)
      getmetatable(proxy).__gc = func
   else -- 5.2
      proxy = {}
      setmetatable(proxy, {__gc=func})
   end
   return proxy
end

return function(func, mutex)
   local threads = require 'threads'

   assert(type(func) == 'function', 'function, [mutex] expected')
   assert(mutex == nil or getmetatable(threads.Mutex).__index == getmetatable(mutex).__index, 'function, [mutex] expected')

   -- make sure mutex is freed if it is our own
   local proxy
   if not mutex then
      mutex = threads.Mutex()
      proxy = newproxygc(
         function()
            mutex:free()
         end
      )
   end

   local mutexid = mutex:id()
   local safe =
      function(...)
         local threads = require 'threads'
         local mutex = threads.Mutex(mutexid)
         local unpack = unpack or table.unpack
         mutex:lock()
         local res = {func(...)}
         mutex:unlock()
         return unpack(res)
      end

   -- make sure mutex is freed if it is our own
   if proxy then
      setfenv(safe, {require=require, unpack=unpack, table=table, proxy=proxy})
   end

   return safe
end