Chapter 9. Serialization rules and options

Table of Contents

9.1. Rules
9.2. Instantiating the storage class - template parameters
9.2.1. Pointer tracking option
9.2.2. Polymorphic pointer option
9.2.3. Backend option
9.3. Instantiating the storage class - constructor parameters
9.4. Selecting third party library support
9.5. Selecting the type traits library
9.6. Selecting RTTI support

9.1. Rules

  • The library is not multithreaded - serialization is performed by the thread which calls the library. It is illegal to call the library using the same storage instance from more than one thread at the same time. It may be safe to call the library from different threads in a mutually exclusive manner (ie, gated via a mutex to produce serial behaviour) but this depends on whether the underlying libraries are thread-safe. For example, if the operating system or SQLite3 library performs a thread unsafe operation, data may be lost / corrupted, or the program may malfunction or even crash. The safest thing to do is to have one thread create the storage instance, and then serialize the object set using the same thread.

  • While data is being stored or retrieved, clients should not be executing code in another thread aside from the serializing thread that modifies the objects that are being stored or retrieved, otherwise the library will crash or malfunction.

  • During serialization, the object set that is being serialized should not: have objects added to it, have objects removed from it, or have any changes made to any object in it. In other words, do not alter the object set in any way until serialization has completed. Note that this also includes object deallocation, so this usage is illegal:

    ccs::serialization::storage<> db("/path/to/some/file.db");
    {
      std::auto_ptr<Person> p(new Person);
      db << p;
    }
    {
      std::auto_ptr<Person> q(new Person);
      db << q;
    }

    ...because object q may end up with the same memory address as object p, causing the library to mistake p and q as the same object, which will cause it to malfunction by not writing out q's data. This usage is legal:

    ccs::serialization::storage<> db("/path/to/some/file.db");
    std::auto_ptr<Person> p(new Person);
    db << p;
    std::auto_ptr<Person> q(new Person);
    db << q;

    ...because p and q can never have the same address.

  • Because the library recursively follows object graphs, graphs with long paths will require large amounts of stack space for the objects to be serialized. If you encounter a stack overflow error during serialization, increase your stack size. Certain compiler options such as disabling stack frames may decrease your stack size requirements. As an example, the serialization library's test program requires 3MB (debug builds) or 2MB (release builds) of stack space because the object cycle tests involve cycles of 1024 linked objects in length.