summaryrefslogtreecommitdiffstats
path: root/README.markdown
blob: 09dedc56f544a0808f1d4c8d9bb1a05f2c7e8d73 (plain) (blame)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
A Lua Event Machine
===================


About
-----

The Lua Event Machine is basically a [Lua][] interpreter with a built-in
[libev][] main loop.

All Lua code is run in coroutines so that modules can suspend the currently
running code, register callbacks with the event loop and wait for events
to happen before resuming the coroutine.

This allows libraries to be written such that calls appear to be blocking,
while still allowing other Lua coroutines to run. One just have to remember
that all global variables (and variables shared in closures) may be changed
by other coroutines when calling functions which might suspend the currently
running coroutine for a while.

This also allows you to write libraries which automatically spawn
new coroutines and runs Lua functions to handle incoming events.

[Lua]: http://www.lua.org/
[libev]: http://libev.schmorp.de/

Installation
------------

Get the sources and do

    $ make install

This will install the `lem` binary to `/usr/local/bin`, a utility
library to `/usr/local/lib/lua/5.1/lem/utils.so` and some C headers
to `/usr/local/include/`.

Use

    $ make clean
    $ make PREFIX=<your custom path> install

to change the install path.

The complete Lua 5.1.4 sources are included so having Lua installed on your
system is not required to build the Lua Event Machine.

Usage
-----

The `lem` interpreter will behave just like the normal standalone Lua
interpreter except there is no built-in REPL. You can indeed run
all your normal Lua scripts using it. Type

    $ lem myscript.lua

to run `myscript.lua` or make the script executable and add a hash-bang
header as in

    #!/usr/bin/env lem

    local utils = require 'lem.utils'

    (etc.)

Just like the normal stand-alone interpreter command line arguments
are stored in the global table `arg` where `arg[-1]` is the interpreter,
`arg[0]` is the script name and normal arguments begin at `arg[1]`.

Running Lua scripts in the Lua Event Machine however, will allow you
to load the lem modules, which will fail in the normal interpreter.

The Utility Library
-------------------

The Lua Event Machine comes with a small utility library which contains
some basic building blocks for spawning new coroutines and synchronizing
between running coroutines.

The library is imported using

    local utils = require 'lem.utils'

This sets `utils` to a table with the following functions.

* __utils.spawn(func, ...)__

  This function schedules the function `func` to be run in a new coroutine.
  Any excess arguments will be given as arguments to `func`.

* __utils.yield()__

  This function suspends the currently running coroutine, but immediately
  schedules it to be run again. This will let any other coroutines scheduled
  to run get their turn before this coroutine continues.

* __utils.exit([status])__

  The function will stop the main loop and exit the Lua Event Machine.
  The only difference between this function and `os.exit()` is that this function
  will let any garbage collection metafunctions run before the program exits.

  If `status` is supplied this will be the exit status of program, otherwise
  `EXIT_SUCCESS` is used.

* __utils.sleeper()__

  This function returns a new sleeper object.

* __sleeper:sleep([seconds])__

  This method suspends the current coroutine.
  If `seconds` is given the method will return `nil, 'timeout'` after
  that many seconds.

  If `seconds` is zero or negative this method will behave as `utils.yield()`
  except it will still return `nil, 'timeout'`.

  If another coroutine is already sleeping on this object the method will
  return `nil, 'busy'`.

  The timeout should have at least milliseconds resolution, but since
  other coroutines could be running, and even more coroutines scheduled
  for running when the timeout occurs, no guarantees can be made as to exactly
  how long time the coroutine will be suspended.

* __sleeper:wakeup(...)__

  This method wakes up any coroutine sleeping on the sleeper object.

  Any arguments given to this method will be returned by the `sleeper:sleep()`
  method called by the sleeping coroutine.

  If no coroutine is currently sleeping on the sleeper object this method
  will return `nil, 'not sleeping'`, otherwise it will return `true`.

* __utils.timer(seconds, func)__

  This method will schedule the function `func` to be run in a new coroutine
  after `seconds` seconds and return a new timer object.

  If `seconds` is zero or negative this method shall behave as `utils.spawn()`
  except it will still return a timer object.

* __timer:cancel()__

  This method cancels the timer. If the coroutine has already been scheduled
  to run this method shall return `nil, 'expired'`, `true` otherwise.


License
-------

The Lua Event Machine is free software. It is distributed under the terms of the
[GNU General Public License][gpl]

[gpl]: http://www.fsf.org/licensing/licenses/gpl.html


Contact
-------

Please send bug reports, patches, feature requests, praise and general gossip
to me, Emil Renner Berthing <esmil@mailme.dk>.