Single instance module and multithreading

From: helgoboss <benjamin.k....at.gmail.com>
Date: Sat, 21 Feb 2009 08:43:07 -0800 (PST)

Hello Mitchell, hello community,

I often use an external file manager or the command line to locate
text files and open them in Textadept (by invoking the Textadept
executable with the path of the text file as argument), I almost never
use the "Open file" command of Textadept. Unfortunately, after a while
I've so many open Textadept instances that I loose track because
there's one Textadept window for each open text file. I'd prefer to
have only one Textadept window for all open text files to avoid chaos
on my Desktop.

The solution would be a "single instance" feature which ensures that
there's never more than one instance of Textadept running. All further
invocations of the Textadept executable would be "redirected" to an
existing Textadept process. As a side effect, that would also shorten
the time to open the text file and save system resources. Such a
feature can be found for example in SciTE ("check.if.already.open"
option). As you already have stated in a former thread (http://
groups.google.com/group/textadept/browse_thread/thread/
f71dd38eb7202781/525f8093b292508f?
lnk=gst&q=instance#525f8093b292508f), this feature probably won't make
its way into the core, understandibly. Nevertheless, I think the
feature is indispensible for some people.

In Textadept, everything is about extensibility, so I tried to add
this feature as a Textadept module. This module uses LuaSocket to do
the inter-process communication stuff in a platform-independent
manner. Sockets are a popular approach to enable "single instance"
support for applications. However, I ran into a serious issue,
explained below, which makes it impossible to get the single instance
module to work.

It's planned to work like this: On startup, Textadept checks whether
port x is free. If yes, it can be assumed that this is the first
Textadept instance, so it starts listening for remote messages on this
port. If not, it can be assumed that this is a second instance, so it
connects to port x and sends a message containing the command line
arguments to the first Textadept instance. After this, the second
instance quits immediately. The first Textadept instance in turn
interprets the message and loads a file into a new buffer.

The showstopper is that Lua has no native support for multithreading.
Listening on a socket means blocking the whole thread of execution -
which would make Textadept unusable if there's only one thread. That's
why it's absolutely necessary to do the listening stuff in a separate
thread. There are some Lua modules out there that enable
multithreading and don't need a modified lua.dll, for example
LuaLanes, but they render unusable because they don't give the
possibility to share global data among threads. However, the socket
listener thread **needs** to access global data, in particular it
needs to access the same "textadept" Lua table like the main thread in
order to have control over Textadept.

I think, the only possibility would be to add multithreading support
in the Textadept core (could be helpful for other modules as well). On
http://lua-users.org/wiki/ThreadsTutorial there's some information
about how to do this. It could work roughly like this: The Textadept
module code written in Lua invokes a function
"textadept.start_in_new_thread(lua_code)" (implemented by the C core)
which executes the specified Lua code in a new thread. In particular,
the C core starts a new thread (pthread or winapi) and initializes a
new Lua state in this thread. It binds all the global data like the
textadept table to the new Lua state and then lets Lua interpret the
specified code.

Unfortunately, threads which share global data also introduce the
problem of race conditions. I've no idea how much effort it would take
to make the Textadept core thread safe.

I would be happy to see some comments on this, thanks. Question to
Mitchell: Do you plan to add multithreading support in future?

Cheers
Received on Sat 21 Feb 2009 - 11:43:07 EST

This archive was generated by hypermail 2.2.0 : Thu 08 Mar 2012 - 11:37:27 EST