diff --git a/docs/scripting.xml b/docs/scripting.xml
index 0aa9ff4a5..45f5682b1 100644
--- a/docs/scripting.xml
+++ b/docs/scripting.xml
@@ -1271,93 +1271,88 @@ socket:close()
threads in NSEmutexes in NSE
- Each thread made for a script (e.g. ftp-anon) will yield to other
- scripts whenever it makes a call on network objects (sending/receiving
- data). Some scripts need finer control over threads' execution. An
+ Each script execution thread (e.g. ftp-anon running against an FTP server on the target host) yields to other
+ scripts whenever it makes a call on network objects (sending or receiving
+ data). Some scripts require finer concurrency control over thread execution. An
example is the whois script which queries
whoiswhois
- servers for each target. Because many concurrent queries often result in
- getting one's IP banned for abuse and a query may return additional
+ servers for each target IP address. Because many concurrent queries often result in
+ getting one's IP banned for abuse, and because a single query may return additional
information for targets other threads are running against, it is useful
- to have other threads pause while one thread is conducting a query.
+ to have other threads pause while one thread performs a query.
- To solve this problem, there is an nmap function,
- mutex, that provides a
+ To solve this problem, NSE includes a
+ mutex function which provides a
mutex
- usable by scripts. The mutex allows for only one thread to be working
- on an object. Threads waiting to work on this object are put in the
- waiting queue until they can get a "lock" on the mutex. A solution for
- the whois problem above is to have each thread
- block on a mutex using a common string,
- thus ensuring only one thread is working so its results can
- be shared with other scripts which may not need to run and so queries
- to the whois servers are staggered.
+ (mutual exclusion object) usable by scripts. The mutex allows
+ for only one thread to be working on an object. Competing threads
+ waiting to work on this object are put in the waiting queue
+ until they can get a "lock" on the mutex. A solution for
+ the whois problem above is to have each
+ thread block on a mutex using a common string, thus ensuring
+ that only one thread is querying whois servers at once. That
+ thread can store the results in the NSE Registry before
+ releasing unlocking the mutex. The next script in the waiting
+ queue can then run. It will first check the Registry and only
+ query whois servers if the previous results were insufficient.
+
+ The first step is to create a mutex object using a statement such as:
+
+ mutexfn = nmap.mutex(object)
+
+ The mutexfn returned is a function
+ which works as a mutex for the object passed
+ in. This object can be any
+ Lua data
+ type except nil,
+ booleans, and numbers.
+ The returned function allows you to lock, try to lock, and
+ release the mutex. Its first and only parameter must be one of
+ the following:
+
+
-
-
-
-
-
-
- Returns a function that works on a mutex for the object passed.
- This object can be any
-
- Lua data type
- except nil,
- booleans, and numbers.
- The returned function allows you to lock, try to lock, and
- release the mutex. Its first and only parameter must be one of the following:
-
-
-
-
- "lock"—Make a blocking lock on the
- mutex. If the mutex is busy
- (another thread has a lock on it), then the thread will
- yield and wait. The function returns with the mutex
- locked.
-
-
-
-
- "trylock"—Makes a non-blocking lock
- on the mutex. If the mutex is
- busy then it immediately returns with a return value of
- false. Otherwise the mutex locks the
- mutex and returns true.
-
-
-
-
- "done"—Releases the mutex and allows
- another thread to lock it.
- If the thread does not have a lock on the mutex, an
- error will be raised.
-
-
-
-
- "running"—Returns the thread locked
- on the mutex or nil if the mutex is not
- locked. This should only be used for debugging as it
- interferes with finished threads from being
- collected.
-
-
-
-
+ "lock"
+ Make a blocking lock on the mutex. If the mutex is busy (another thread has a lock on it), then the thread will yield and wait. The function returns with the mutex locked.
-
+
+
+ "trylock"
+ Makes a non-blocking lock on the mutex. If the mutex is
+ busy then it immediately returns with a return value of
+ false. Otherwise the mutex locks the
+ mutex and returns true.
+
+
+
+ "done"
+ Releases the mutex and allows
+ another thread to lock it. If the thread does not have a lock on the mutex, an
+ error will be raised.
+
+
+
+ "running"
+ Returns the thread locked
+ on the mutex or nil if the mutex is not
+ locked. This should only be used for debugging as it
+ interferes with garbage collection of finished threads.
+
+
+
+A simple example of using the API is provided in . For real-life examples, read the asn-query.nse and whois.nse scripts in the Nmap distribution.
+
Mutex manipulation
local mutex = nmap.mutex("My Script's Unique ID");
function action(host, port)
mutex "lock";
- -- do stuff
+ -- Do critical section work - only one thread at a time executes this.
mutex "done";
return script_output;
end