views:

116

answers:

1
+1  Q: 

Tinyxml Multi Task

I have a single xml file and every new thread of the program (BHO) is using the same Tinyxml file.

every time a new window is open in the program, it runs this code:

const char * xmlFileName = "C:\\browsarityXml.xml";
TiXmlDocument doc(xmlFileName);
doc.LoadFile();
//some new lines in the xml.. and than save:
doc.SaveFile(xmlFileName);

The problem is that after the first window is adding new data to the xml and saves it, the next window can't add to it. although the next one can read the data in the xml, it can't write to it.

I thought about two possibilities to make it work, but I don't know how to implement them:

  1. Destroy the doc object when I'm done with it.
  2. Some function in Tinyxml library to unload the file.

Any help or better understanding of the problem will be great. Thanks.

+1  A: 

Update based on comments (scrap previous answer):

OK, I didn't see much in the TinyXml documentation that tells us how to open a document without restriction to other threads.

What you should do in this case is declare only one instance to the TiXmlDocument and share it between threads. Whenever a thread writes to the file it will enter a critical section, write what it needs to write, save the file, then exit the critical section.

I don't see another workaround.

Update per comments:
Since you're using MFC threads your code should look something like this:

class SafeTinyXmlDocWrapper
{
private:
    static bool m_isAlive = FALSE;
    static CCriticalSection m_criticalSection;
    char* m_xmlFileName;
    TiXmlDocument m_doc;

public:

    SafeTinyXmlDocWrapper()
    {
        m_xmlFileName = "C:\\browsarityXml.xml";
        m_doc = TiXmlDocument(m_xmlFileName);
        m_doc.LoadFile();
        m_isAlive = TRUE;
    }

    ~SafeTinyXmlDocWrapper()
    {
        CSingleLock lock(&m_criticalSection);
        lock.Lock(); // only one thread can lock

        m_isAlive = FALSE;

        // cleanup and dispose of the document

        lock.Unlock();
    }

    void WriteBatch(BatchJob& job)
    {
        CSingleLock lock(&m_criticalSection);
        lock.Lock(); // only one thread can lock
        if(m_isAlive) // extra protection in case the destructor was called
        {
            // write the batch job to the xml document

            // save the xml document
            m_doc.SaveFile(m_xmlFileName);
        }
        lock.Unlock(); // the thread unlocks once it's done
    }
}

I have not written C++ in some time now, but it should be roughly what you're looking for. Bells and whistles cost extra :).

Lirik
my question was, how do I clean up? and what exactly should I clean up?
shaimagz
I think the better thing to do in this case is to share the XML document between threads and send it batch jobs from each thread. The batch job will be written to the xml file and saved under a lock/critical section.
Lirik
Sharing object between threads isn't in my level of programming yet, but I'll try it. thanks.
shaimagz
I think this case is simple enough that it should be both easy and a good learning example. What are the threads used in your code: pthreads, MFC threads, boost threads?
Lirik
MFC threads.. I'm doing a BHO (Browser Helper Object) - IE Add-on.
shaimagz
after I got a lot of errors I found that I need to include "afxmt.h".but now I get this error. "Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]". I added "#define _AFXDLL" to my code but I still get this error.
shaimagz