views:

567

answers:

4

In my sample application, I have basically two threads.

The main thread contains a Lua engine (which is not thread-safe) and registers some C++ functions into this engine. However, one of these functions takes too long to perform (since it downloads some file over the internet) and I want the Lua engine to continue doing other stuff without blocking during the download process.

Therefore, I want to make it asynchronous: When the downloadFile() function is called from Lua, I create a new thread which performs the download. Then, the function returns and the Lua engine can process other work. When the download is finished, the second thread somehow needs to tell the main thread that it should somehow call some additional function processFile() to complete it.

This is where I'm struggling now: What is the easiest / cleanest solution to achieve this?

+1  A: 

Without integrating multithreading into lua ( which isn't that hard, Lua is already prepared for it ), your only solution is to handle the signaling in c++.

From what you've said, there isn't any interaction with Lua in the thread downloadFile() creates, does Lua have to call processFile()? If not, what's stopping you from handling it all in c++? If you need to notify Lua, you can always use a callback function ( save it in the registry ), handle the signal in c++ and run the callback.

Since your engine is not thread-safe, I don't think there is a way to handle it in Lua.

Neruz
+2  A: 

Try LuaLanes for instance. Also here.

lhf
+2  A: 

A new user-data object can be returned by your downloadFile() or similarly named function for kicking off the thread. This new user-data object would contain the thread handle and have an associated meta-table with an __index entry that would have a function for checking the completion status of the download, and contain other synchronization functions.

Possibly looking like this:

local a = downloadFile("foo")

-- do other things

a:join() -- now let the download finish

processFile()

or this:

local a = downloadFile("foo")

local busywork = coroutine.create(doOtherStuff)

while(not a:finished()) do
  coroutine.resume(busywork)
end

processFile()
gwell
What if you don't expect the download to finish and just want to get notified when a download finished? Or, in some other environment: what if you have some main thread and you have a second thread, taking some user input for example and you want to interrupt the main thread as soon as the user inputs something? You can't know WHEN you have to join() the two threads since you don't know when the user will input something.
Etan
`join()` is just an example of a possible synchronization call. Polling for download status would still be simple with a `finished()` type function.
gwell
A: 

Return a "future" object from the downloadFile function. This can be used to check the result of the long-running asynchronous operation. See java.util.concurrent.Future or QFuture for example implementations. Also, check out this mailing list thread for a discussion of implementing futures/promises in Lua using coroutines.

Judge Maygarden