Motivation
I am creating a system of two scripts currently where one script handles menus and other data operation which need a fast response while the other script is used for sending instant messages (which have 2 seconds delay). And one of the operations can potentially create a large number of sent messages. I can not make the one script prepare the message text in LSD and let the other one send the messages from there, because LSD is used to hold the needed data and I can need the full storage.
The solution I came up with was to send the text for each IM in a separate link message and send those link messages as soon the comm script is ready. This would lead to using two link messages, one (core -> comm) that takes the body of the IM to send and the other (comm -> core) that requests the new one. This solution, however slows down the process. Ideally would be to send a bunch of link messages with text at once and wait until the comm script has handled them. But that can lead to overflowing the event queue if not used carefully.
This leads to a semaphore approach: We use a certain KVP on the LSD, say with a key "semaphore". The value is initialized by "0". Whenever a core script sends a link message it increases this value by 1 and stops doing so when the value reached a certain threshold, maybe 16. When the comm script sends the instant message, it decreases the value by 1. Once it crossed the threshold (we can use a second threshold for example 8) the core script resumes generating link messages to send.
This solution even allows to keep the message generating part within one function within one event: the generator would use busy waiting where it observes the semaphore value to know if it can generate new link messages, although this would break the "fast response" idea, but it is good for other applications.
The solution has only one problem: To update the KVP, a script has to use the llLinksetDataRead and then llLinksetDataWrite operations and since both scripts would call this couple they can do this in the same moment and corrupt the value. Because of this LSD needs a way of atomic value incrementation.
Suggestion
The semaphore is a regular KVP which is initialized by an integer value casted to a string, for example "0".
For the update of this value we need one unprotected and one protected operation:
integer llLinksetDataIncrement(string name, integer increment);
This operation replaces this code:
integer value = (integer)llLinksetDataRead(name);
value = valie + increment;
llLinksetDataWrite(name, (string)value);
return value;
But this code block must be embedded into a critical section not allowing the value to be changed by an other script in between.
This single operation allows to increment the value, decrement it (use a negative increment) and also read it (use a zero increment but you may also use a regular llLinksetDataRead here) and I think it is fully sufficient for many semaphore applications.
The scripter must be sure not to use the regular llLinksetDataWrite to not to corrupt the semaphore value.
The protected operation is similar but it accesses a protected KVP and thus uses a password:
integer llLinksetDataIncrementProtected(string name, integer increment, string password);