My favorites | Sign in
Project Logo
                
Details: Show all Hide all

Last 30 days

  • Dec 21, 2009
    r189 (Just a comment ) committed by t...@tibsnjoan.co.uk   -   Just a comment
    Just a comment
  • Dec 18, 2009
    r188 (A Limpet that listens for KBUS messages... ) committed by t...@tibsnjoan.co.uk   -   A Limpet that listens for KBUS messages...
    A Limpet that listens for KBUS messages...
  • Dec 18, 2009
    r187 (Start coding a Limpet ) committed by t...@tibsnjoan.co.uk   -   Start coding a Limpet
    Start coding a Limpet
  • Dec 17, 2009
    issue 17 (We need a way to synchronise kbuses ) reported by rrw@kynesim.co.uk   -   All kbuses currently have independent message ids. This means that message ids on bus A are meaningless on bus B, so that if (P,R) and Q run on A and B, respectively: P->R: "Foo" msgid=14 P->Q: "Did you get msgid=14"? Can never work - Q will never know which of its message-ids corresponds to msgid=14, so can never figure out if it should wait for msgid 14 or if it has missed the message. This particularly hurts because this situation comes up when waiting for daemons to start and in some scenarios involving out-of-band communication with multiple busses. One solution would be to remember a set of (network-id, last-msg) pairs. One could then infer that "the current message-id must have happened after (network-id,last-msg)" and if Q ever saw, say, (A, N) where N >= 14 in its set, it would know that message-id 14 had happened and that if it were going to receive it at all, it would've by now.
    All kbuses currently have independent message ids. This means that message ids on bus A are meaningless on bus B, so that if (P,R) and Q run on A and B, respectively: P->R: "Foo" msgid=14 P->Q: "Did you get msgid=14"? Can never work - Q will never know which of its message-ids corresponds to msgid=14, so can never figure out if it should wait for msgid 14 or if it has missed the message. This particularly hurts because this situation comes up when waiting for daemons to start and in some scenarios involving out-of-band communication with multiple busses. One solution would be to remember a set of (network-id, last-msg) pairs. One could then infer that "the current message-id must have happened after (network-id,last-msg)" and if Q ever saw, say, (A, N) where N >= 14 in its set, it would know that message-id 14 had happened and that if it were going to receive it at all, it would've by now.
  • Dec 17, 2009
    r186 (Initial commit of some sandbox stuff. ) committed by t...@tibsnjoan.co.uk   -   Initial commit of some sandbox stuff.
    Initial commit of some sandbox stuff.
  • Dec 15, 2009
    r185 (And thus it has gone... ) committed by t...@tibsnjoan.co.uk   -   And thus it has gone...
    And thus it has gone...
  • Dec 15, 2009
    r184 (Move the (by now) traditional temporary work file from the k...) committed by t...@tibsnjoan.co.uk   -   Move the (by now) traditional temporary work file from the kernel module directory.
    Move the (by now) traditional temporary work file from the kernel module directory.
  • Dec 15, 2009
    r183 (Move the Python code into its own directory - it is stronly ...) committed by t...@tibsnjoan.co.uk   -   Move the Python code into its own directory - it is stronly arguable that it no longer made sense to keep it in the kernel module's directory.
    Move the Python code into its own directory - it is stronly arguable that it no longer made sense to keep it in the kernel module's directory.
  • Dec 15, 2009
    r182 (Move the Python code around a bit, to make a proper package....) committed by t...@tibsnjoan.co.uk   -   Move the Python code around a bit, to make a proper package. The unit tests still work - in the directory containing the package, one can do:: nosetests kbus -d --doctest-tests --with-doctest
    Move the Python code around a bit, to make a proper package. The unit tests still work - in the directory containing the package, one can do:: nosetests kbus -d --doctest-tests --with-doctest
  • Dec 15, 2009
    r181 (Release 0.1 before I start development on user-space daemons...) committed by t...@tibsnjoan.co.uk   -   Release 0.1 before I start development on user-space daemons.
    Release 0.1 before I start development on user-space daemons.
  • Dec 15, 2009
    r180 (Tag the sources before I start work on user-space KBUS daemo...) committed by t...@tibsnjoan.co.uk   -   Tag the sources before I start work on user-space KBUS daemons, and consequent support for peer-to-peer inter-machine comminications. This will also involve reorganisation of the KBUS Python code.
    Tag the sources before I start work on user-space KBUS daemons, and consequent support for peer-to-peer inter-machine comminications. This will also involve reorganisation of the KBUS Python code.
  • Dec 08, 2009
    1 issue changed by t...@tibsnjoan.co.uk   -   Issue 15
    Issue 15
  • Dec 08, 2009
    r179 (Remove some redundant return values - issue 15. And remove ...) committed by tony.ibbs   -   Remove some redundant return values - issue 15 . And remove a redundant comment.
    Remove some redundant return values - issue 15 . And remove a redundant comment.

Older

  • Dec 04, 2009
    issue 16 (/proc/kbus/bindings output incorrect) commented on by dlafferty   -   Never mind the second point about the header comments. This is not a problem, as kbus is merely printing out a new header for each kbus device.
    Never mind the second point about the header comments. This is not a problem, as kbus is merely printing out a new header for each kbus device.
  • Dec 04, 2009
    issue 16 (/proc/kbus/bindings output incorrect) reported by dlafferty   -   The bindings reporting buffer may not be being cleared properly as it reports pid's where there is no such process. E.g. below, the pids 1192, 7752 and 7675 all do not exist when 'ps w' is used to inspect all process ids. Further, the header comment appears multiple times. This is relevant, because the header is supposed to be the start of the information. This suggests the items before the last header may be garbage. # cat /proc/kbus/bindings # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> 0: 9700 1192 L $.m0.player.0.command.% 0: 9700 1192 L $.m0.attentiond.0.event.StreamControls 0: 9700 1192 L $.m0.attentiond.0.event.StreamClosed 0: 9700 1192 L $.m0.gozer.0.event.% 0: 688 7752 L $.m0.gozer.0.event.windowopened 0: 680 7675 L $.m0.stb.system.query.% # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> #
    The bindings reporting buffer may not be being cleared properly as it reports pid's where there is no such process. E.g. below, the pids 1192, 7752 and 7675 all do not exist when 'ps w' is used to inspect all process ids. Further, the header comment appears multiple times. This is relevant, because the header is supposed to be the start of the information. This suggests the items before the last header may be garbage. # cat /proc/kbus/bindings # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> 0: 9700 1192 L $.m0.player.0.command.% 0: 9700 1192 L $.m0.attentiond.0.event.StreamControls 0: 9700 1192 L $.m0.attentiond.0.event.StreamClosed 0: 9700 1192 L $.m0.gozer.0.event.% 0: 688 7752 L $.m0.gozer.0.event.windowopened 0: 680 7675 L $.m0.stb.system.query.% # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> # <device> is bound to <KSock-ID> in <process-PID> as <Replier|Listener> for <message-name> #
  • Dec 02, 2009
    r178 (Fix errors detected when building an ASTB: * Use gcc instea...) committed by tony.ibbs   -   Fix errors detected when building an ASTB: * Use gcc instead of ld, because (a) gcc can act as the linker, and (b) it knows where to find libc when cross-compiling, which ld does not. * It's '-soname=<name>', not '-soname <name>'.
    Fix errors detected when building an ASTB: * Use gcc instead of ld, because (a) gcc can act as the linker, and (b) it knows where to find libc when cross-compiling, which ld does not. * It's '-soname=<name>', not '-soname <name>'.
  • Nov 27, 2009
    1 issue changed by t...@tibsnjoan.co.uk   -   Issue 8
    Issue 8
  • Nov 27, 2009
    issue 8 (Sender should be able to provoke start of a Listener process) commented on by t...@tibsnjoan.co.uk   -   So, if a Sender sends a Request for which no-one has bound as Replier (question: what if there are people bound as Listeners? then we still want a Replier to "spring into existence"), then KBUS should create a KSock for the other end, and pass it up to udev to either create a new process which is given that KSock, or close the KSock (in which case the normal "other end gone away" status will be returned). Secondary issue: allow the same sort of mechanism for if there are no Listeners at all (i.e., to try to make one). How to say we want this? The simplest way may be to add a flag to a message saying magically produce a Listener or Replier (as appropriate) if there isn't one (so two flags, one each)
    So, if a Sender sends a Request for which no-one has bound as Replier (question: what if there are people bound as Listeners? then we still want a Replier to "spring into existence"), then KBUS should create a KSock for the other end, and pass it up to udev to either create a new process which is given that KSock, or close the KSock (in which case the normal "other end gone away" status will be returned). Secondary issue: allow the same sort of mechanism for if there are no Listeners at all (i.e., to try to make one). How to say we want this? The simplest way may be to add a flag to a message saying magically produce a Listener or Replier (as appropriate) if there isn't one (so two flags, one each)
  • Nov 24, 2009
    issue 15 (Tidy up irrelevant return values in kbus.py) reported by t...@tibsnjoan.co.uk   -   Various methods in kbus.py (notably, fcnt.ioctl callers where the result is 0 or an exception) return a value when it would be better not to. Refactor to remove irrelevant returns.
    Various methods in kbus.py (notably, fcnt.ioctl callers where the result is 0 or an exception) return a value when it would be better not to. Refactor to remove irrelevant returns.
  • Nov 23, 2009
    issue 14 (When creating a new Message, an invalid message name gives a...) reported by t...@tibsnjoan.co.uk   -   The following is not giving a helpful error message! >>> Message('Fred') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "kbus.py", line 779, in __init__ self.msg = entire_message_from_string(arg) File "kbus.py", line 608, in entire_message_from_string return _struct_from_string(local_class, data) File "kbus.py", line 343, in _struct_from_string thing = struct_class() MemoryError
    The following is not giving a helpful error message! >>> Message('Fred') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "kbus.py", line 779, in __init__ self.msg = entire_message_from_string(arg) File "kbus.py", line 608, in entire_message_from_string return _struct_from_string(local_class, data) File "kbus.py", line 343, in _struct_from_string thing = struct_class() MemoryError
  • Nov 18, 2009
    1 issue changed by t...@tibsnjoan.co.uk   -   Issue 5
    Issue 5
  • Nov 18, 2009
    r177 (The /proc/kbus files should not now be limited to a single p...) committed by tony.ibbs   -   The /proc/kbus files should not now be limited to a single page in length
    The /proc/kbus files should not now be limited to a single page in length
  • Nov 18, 2009
    r176 (As part of investigating issue 13, add the process PID to th...) committed by tony.ibbs   -   As part of investigating issue 13, add the process PID to the information reported in /proc/kbus/bindings
    As part of investigating issue 13, add the process PID to the information reported in /proc/kbus/bindings
  • Nov 18, 2009
    issue 13 (Bindings hang around after bound process is killed) reported by rrw@kynesim.co.uk   -   After I've killed my emaild process: 0: 721 R $.m0.net.sendemail hangs around in /proc/kbus/bindings and I can't rebind to that symbol despite having killed all the processes that might bind it. Killing any process that might be stuck sending a message to it doesn't release it either. I suspect this is another 'failing to release resources when a process dies unexpectedly' bug.
    After I've killed my emaild process: 0: 721 R $.m0.net.sendemail hangs around in /proc/kbus/bindings and I can't rebind to that symbol despite having killed all the processes that might bind it. Killing any process that might be stuck sending a message to it doesn't release it either. I suspect this is another 'failing to release resources when a process dies unexpectedly' bug.
  • Nov 10, 2009
    1 issue changed by t...@tibsnjoan.co.uk   -   Issue 9
    Issue 9
  • Nov 10, 2009
    r175 (In pursuit of issue 9, add a call to the C library. ) committed by tony.ibbs   -   In pursuit of issue 9 , add a call to the C library.
    In pursuit of issue 9 , add a call to the C library.
  • Nov 10, 2009
    1 issue changed by t...@tibsnjoan.co.uk   -   Issue 9
    Issue 9
  • Nov 10, 2009
    r174 (Update documentation, pursuant to issue 9. ) committed by tony.ibbs   -   Update documentation, pursuant to issue 9 .
    Update documentation, pursuant to issue 9 .
  • Nov 10, 2009
    r173 (Finishing issue 9: array concerned is now an array of pointe...) committed by tony.ibbs   -   Finishing issue 9 : array concerned is now an array of pointers (saving some considerable space)
    Finishing issue 9 : array concerned is now an array of pointers (saving some considerable space)
  • Nov 10, 2009
    r172 (Address issue 9 - allow dynamic extension of the number of K...) committed by tony.ibbs   -   Address issue 9 - allow dynamic extension of the number of KBUS devices. Note: this is a first-pass solution, and there is still work to be done, specifically making the KBUS device array store pointers-to-devices rather than being an array of devices (see the code).
    Address issue 9 - allow dynamic extension of the number of KBUS devices. Note: this is a first-pass solution, and there is still work to be done, specifically making the KBUS device array store pointers-to-devices rather than being an array of devices (see the code).
  • Nov 10, 2009
    issue 9 (Want to be able to dynamically create new KBUS devices) commented on by t...@tibsnjoan.co.uk   -   At the moment, the KBUS kernel module can be told at "insmod" time how many devices to allocate. The "alloc_chrdev_region" call that does this is then called to reserve exactly that number of minor device numbers. "alloc_chrdev_region" and "register_chrdev" (internally) both call the same function to do their work, but "alloc_chrdev_region" calls it with the number given, and "register_chrdev" (which is the older mechanism, and is meant to be deprecated) calls it with 256. So. Presumably a sensible approach is to: 1. Allow KBUS to continue to pre-allocate actual devices as it does at the moment (so the user can request that, for instance, 3 devices be created when the kernel module starts up) - this allow existing usage to continue as-is, and makes sense when the system designer knows in advance that a particular number of devices will be needed. 2. Internally, however, it should actually allocate "space" for N minor devices, where N probably is 256. This seems like a sensible hard limit, and there is clearly precedence for using this number. It should be a named constant in the code so it can be changed later if necessary (and to make it easier to range check against). 3. A new IOCTL should then be provided to allow the user-space program to ask that a new device be introduced, with the next available device number. I propose to ignore the idea of removing a device.
    At the moment, the KBUS kernel module can be told at "insmod" time how many devices to allocate. The "alloc_chrdev_region" call that does this is then called to reserve exactly that number of minor device numbers. "alloc_chrdev_region" and "register_chrdev" (internally) both call the same function to do their work, but "alloc_chrdev_region" calls it with the number given, and "register_chrdev" (which is the older mechanism, and is meant to be deprecated) calls it with 256. So. Presumably a sensible approach is to: 1. Allow KBUS to continue to pre-allocate actual devices as it does at the moment (so the user can request that, for instance, 3 devices be created when the kernel module starts up) - this allow existing usage to continue as-is, and makes sense when the system designer knows in advance that a particular number of devices will be needed. 2. Internally, however, it should actually allocate "space" for N minor devices, where N probably is 256. This seems like a sensible hard limit, and there is clearly precedence for using this number. It should be a named constant in the code so it can be changed later if necessary (and to make it easier to range check against). 3. A new IOCTL should then be provided to allow the user-space program to ask that a new device be introduced, with the next available device number. I propose to ignore the idea of removing a device.
  • Nov 09, 2009
    issue 12 (Document the C library) reported by t...@tibsnjoan.co.uk   -   Write Sphinx documentation for the C library, including examples.
    Write Sphinx documentation for the C library, including examples.
  • Nov 09, 2009
    issue 11 (Review the C library API and implementation) reported by t...@tibsnjoan.co.uk   -   The C library needs reviewing.
    The C library needs reviewing.
  • Nov 09, 2009
    issue 10 (Implement non-kernel-module KBUS) reported by t...@tibsnjoan.co.uk   -   As a first step towards other things (particularly, the cross-network KBUS support), implement a user-space alternative to the KBUS kernel module. The first implementation should probably be in Python, and should be able to use the same (or a subset of the same) unit tests as the Python bindings for the kernel module system. A C version should then be relatively easy to produce, and this may form the basis for the networking infrastructure.
    As a first step towards other things (particularly, the cross-network KBUS support), implement a user-space alternative to the KBUS kernel module. The first implementation should probably be in Python, and should be able to use the same (or a subset of the same) unit tests as the Python bindings for the kernel module system. A C version should then be relatively easy to produce, and this may form the basis for the networking infrastructure.
  • Nov 09, 2009
    issue 9 (Want to be able to dynamically create new KBUS devices) reported by t...@tibsnjoan.co.uk   -   At the moment, the number of KBUS devices is determined when the KBUS kernel module is installed (by "insmod" or whatever). It would be good to be able to do this at run time. It would also be good to be able to use file permissions to restrict user access to a KBUS device (i.e., only able to use it if the permissions allow).
    At the moment, the number of KBUS devices is determined when the KBUS kernel module is installed (by "insmod" or whatever). It would be good to be able to do this at run time. It would also be good to be able to use file permissions to restrict user access to a KBUS device (i.e., only able to use it if the permissions allow).
  • Nov 09, 2009
    issue 8 (Sender should be able to provoke start of a Listener process) reported by t...@tibsnjoan.co.uk   -   A sender should be able to send a message to a process that does not yet exist. (nb: in the following, "KBUS" means "the KBUS kernel module") The proposed mechanism is to "mark" that this is wanted, indicating what process is wanted, and then have KBUS use the existing hotplug (udev) mechanisms to start the process (thus taking as much advantage as possible of known-working technology). It may be that in order not to "lose" the initial message (which we're assuming the new process will want to receive) KBUS should also bind the new KSock for the process and tell it about it. This needs thought. Question: should this *require* the new process to be started, or do we want a mode for "start a process if there is no existing listener"? Maybe both.
    A sender should be able to send a message to a process that does not yet exist. (nb: in the following, "KBUS" means "the KBUS kernel module") The proposed mechanism is to "mark" that this is wanted, indicating what process is wanted, and then have KBUS use the existing hotplug (udev) mechanisms to start the process (thus taking as much advantage as possible of known-working technology). It may be that in order not to "lose" the initial message (which we're assuming the new process will want to receive) KBUS should also bind the new KSock for the process and tell it about it. This needs thought. Question: should this *require* the new process to be started, or do we want a mode for "start a process if there is no existing listener"? Maybe both.
  • Oct 21, 2009
    1 issue changed by t...@tibsnjoan.co.uk   -   Issue 7
    Issue 7
  • Oct 21, 2009
    r171 (Addressing issue 7 - make it clearer what is going on with "...) committed by tony.ibbs   -   Addressing issue 7 - make it clearer what is going on with "entire" message creation functions in the C API, and make the length limit a bit more sensible.
    Addressing issue 7 - make it clearer what is going on with "entire" message creation functions in the C API, and make the length limit a bit more sensible.
  • Oct 21, 2009
    issue 7 (C programmers creating entire messages, unhappy with the len...) reported by t...@tibsnjoan.co.uk   -   It is not clear from the C library function documentation (in the C library include file, lib/kbus.h) that the "create_entire" message functions are fraught with danger - specifically, that they let you create an entire message of any length, which the KBUS kernel module may then reject as too long. The intent is that messages being sent should be "pointy" messages (which have no such limit). To address this: 1. rename kbus_msg_create_entire as kbus_msg_create_short 2. rename kbus_msg_create_entire_reply as kbus_msg_create_short_reply 3. enforce the length limit in the C library function (it's with respect to a #define from the kernel header file, so that's not too bad a code duplication) 4. en route, change the (rather arbitrary) limit of 2000 bytes to (slightly less arbitrary) 2048 5. document the two "short" functions as (a) having this length limitation, and (b) as not being the preferred way to create messages (really, it's only sensible if the "copies the strings" part of their functionality is needed).
    It is not clear from the C library function documentation (in the C library include file, lib/kbus.h) that the "create_entire" message functions are fraught with danger - specifically, that they let you create an entire message of any length, which the KBUS kernel module may then reject as too long. The intent is that messages being sent should be "pointy" messages (which have no such limit). To address this: 1. rename kbus_msg_create_entire as kbus_msg_create_short 2. rename kbus_msg_create_entire_reply as kbus_msg_create_short_reply 3. enforce the length limit in the C library function (it's with respect to a #define from the kernel header file, so that's not too bad a code duplication) 4. en route, change the (rather arbitrary) limit of 2000 bytes to (slightly less arbitrary) 2048 5. document the two "short" functions as (a) having this length limitation, and (b) as not being the preferred way to create messages (really, it's only sensible if the "copies the strings" part of their functionality is needed).
  • Oct 20, 2009
    r170 (Make the library and test utility support cross compilation ) committed by tony.ibbs   -   Make the library and test utility support cross compilation
    Make the library and test utility support cross compilation
  • Oct 07, 2009
    issue 4 (Refactor debugging messages) commented on by t...@tibsnjoan.co.uk   -   Revison 169 introduces the VERBOSE ioctl, which can be used to switch verbose kernel messages on/off at runtime. This should address item 1.
    Revison 169 introduces the VERBOSE ioctl, which can be used to switch verbose kernel messages on/off at runtime. This should address item 1.
  • Oct 07, 2009
    r169 (In partial satisfaction of issue 4, make verbose kernel mess...) committed by tony.ibbs   -   In partial satisfaction of issue 4, make verbose kernel messages switchable at runtime.
    In partial satisfaction of issue 4, make verbose kernel messages switchable at runtime.
  • Oct 07, 2009
    1 issue changed by t...@tibsnjoan.co.uk   -   Issue 6
    Issue 6
  • Oct 07, 2009
    r168 (This fixes issue 6 (or, at least, the unit test I derived fo...) committed by tony.ibbs   -   This fixes issue 6 (or, at least, the unit test I derived for it).
    This fixes issue 6 (or, at least, the unit test I derived for it).
  • Oct 07, 2009
    issue 6 (Mistake in counting outstanding requests) reported by tony.ibbs   -   Gareth Bailey discovered an issue when sending requests / receiving replies. Broadly, KBUS loses track of the fact that the sender is still owed a reply. See attached files... dmesg.txt shows it clearly. temp.py appears to be a minimal script to reproduce it in a linear manner.
    Gareth Bailey discovered an issue when sending requests / receiving replies. Broadly, KBUS loses track of the fact that the sender is still owed a reply. See attached files... dmesg.txt shows it clearly. temp.py appears to be a minimal script to reproduce it in a linear manner.
  • Oct 07, 2009
    r167 (Move the "announcement" messages for the externally "visible...) committed by tony.ibbs   -   Move the "announcement" messages for the externally "visible" interfaces (kbus_write, etc.) so that the printk is *after* the semaphore has been acquired. This means we'll lose debug if the semaphore isn't gotten, but when two processes are both calling KBUS, the "gone into the function" message will always be associated with the "and this is what I did there" messages - something that wasn't guaranteed before, and which could cause some problems in trying to understand the debugging output.
    Move the "announcement" messages for the externally "visible" interfaces (kbus_write, etc.) so that the printk is *after* the semaphore has been acquired. This means we'll lose debug if the semaphore isn't gotten, but when two processes are both calling KBUS, the "gone into the function" message will always be associated with the "and this is what I did there" messages - something that wasn't guaranteed before, and which could cause some problems in trying to understand the debugging output.
  • Oct 02, 2009
    r166 (kmsg can now take an argument to tell it which bus to listen...) committed by rrw@kynesim.co.uk   -   kmsg can now take an argument to tell it which bus to listen on.
    kmsg can now take an argument to tell it which bus to listen on.
  • Sep 23, 2009
    r165 (In the kbus kernel module Makefile, don't use "?=" when I wa...) committed by tony.ibbs   -   In the kbus kernel module Makefile, don't use "?=" when I want to allow a variable containing whitespace to be considered as unset. Use "ifeq" instead.
    In the kbus kernel module Makefile, don't use "?=" when I want to allow a variable containing whitespace to be considered as unset. Use "ifeq" instead.
  • Sep 22, 2009
    r164 (Update the kbus.py generated docuentation. ) committed by tony.ibbs   -   Update the kbus.py generated docuentation.
    Update the kbus.py generated docuentation.
  • Sep 22, 2009
    r163 (Update the documentation to describe MSGONLYONCE. ) committed by tony.ibbs   -   Update the documentation to describe MSGONLYONCE.
    Update the documentation to describe MSGONLYONCE.
 
Hosted by Google Code