Wednesday, February 9, 2011

C++: Multithreading and refcounted object

I'm currently trying to pass a mono threaded program to multithread. This software do heavy usage of "refCounted" objects, which lead to some issues in multithread. I'm looking for some design pattern or something that might solve my problem.

The main problem is object deletion between thread, normally deletion only decrement the reference counting, and when refcount is equal to zero, then the object is deleted. This work well in monothread program, and allow some great performance improvement with copy of big object.

However, in multithread, two threads might want to delete the same object concurrently, as the object is protected by a mutex, only one thread delete the object and block the other one. But when it releases the mutex, then the other thread continue its execution with invalid (freed object), which lead to memory corruption.

Here is an example with this class RefCountedObject

class RefCountedObject
{
public:
RefCountedObject()
: _refCount( new U32(1) )
{}

RefCountedObject( const RefCountedObject& obj )
: _refCount( obj._refCount )
{
 ACE_Guard< ACE_Mutex > guard( _refCountMutex );
 ++(*_refCount);
}

~RefCountedObject()
{
 Destroy();
}

RefCountedObject& operator=( const RefCountedObject& obj )
{
    if( this != &obj )
    {
        Destroy();
  ACE_Guard< ACE_Mutex > guard( _refCountMutex );
        _refCount = obj._refCount;
        ++(*_refCount);
    }

    return *this;
}

private:
    void Destroy()
 {
  ACE_Guard< ACE_Mutex > guard( _refCountMutex );  // thread2 are waiting here
        --(*_refCount);         // This cause a free memory write by the thread2
        if( 0 == *_refCount )
            delete _refCount;
 }

private:
    mutable U32* _refCount;
    mutable ACE_Mutex _refCountMutex; // BAD: this mutex only protect the refCount pointer, not the refCount itself
};

Suppose that two threads want to delete the same RefCountedObject, both are in ~RefCountedObject and call Destroy(), the first thread has locked the mutex and the other one is waiting. After the deletion of the object by the first thread, the second will continue its execution and cause a free memory write.

Anyone has experience with a similar problem and found a solution ?


Thanks all for your help, I realize my mistake: The mutex is only protecting refCount pointer, not the refCount itself! I've created a RefCount class which is mutex protected. The mutex is now shared between all refCounted object.

Now all works fine.

  • Surely each thread simply needs to manage the reference counts correctly... That is, if ThreadA and ThreadB are both working with Obj1 then BOTH ThreadA and ThreadB should own a reference to the object and BOTH should call release when they're done with the object.

    In a single threaded application it's likely that you have a point where a reference counted object is created, you then do work on the object and eventually call release. In a multi-threaded program you would create the object and then pass it to your threads (however you do that). Before passing the object to the thread you should call AddRef() on your object to give the thread its own reference count. The thread that allocated the object can then call release as it's done with the object. The threads that are working with the object will then call release when they're done and when the last reference is released the object will be cleaned up.

    Note that you dont want the code that's running on the threads themselves to call AddRef() on the object as you then have a race condition between the creating thread calling release on the object before the threads that you've dispatched to get a chance to run and call AddRef().

  • Any object that you are sharing between threads should be protected with a mutex, and the same applies to refcount handles ! That means you will never be deleting the last one handle to an object from two threads. You might be concurrently deleting two distinct handles that happen to point to one object.

    In Windows, you could use InterlockedDecrement. This ensures that precisely one of the two decrements will return 0. Only that thread will delete the refcounted object.

    Any other thread cannot have been copying one of the two handles either. By common MT rules one thread may not delete an object still used by another thread, and this extends to refcount handles too.

    From MSalters
  • One solution is to make the reference counter an atomic value, so that each concurrent call to destroy can safely proceed with only 1 deletion actually occurring, the other merely decrementing the atomic reference count.

    The Intel Thread Building Blocks library (TBB) provides atomic values.

    Also, so does the ACE library in the ACE_Atomic_Op template.

    The Boost library provides a reference counting smart pointer library that already implements this.

    http://www.dre.vanderbilt.edu/Doxygen/Current/html/ace/a00029.html http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm

    From grrussel
  • I believe something along this line would solve your problem:

    private:
        void Destroy()
        {
    ACE_Guard< ACE_Mutex > guard( _refCountMutex ); // thread2 are waiting here if (_refCount != 0) { --(*_refCount); // This cause a free memory write by the thread2 if( 0 == *_refCount ) { delete _refCount; _refcount = 0; } } } private: mutable U32* _refCount; mutable ACE_Mutex _refCountMutex;

    From tloach
  • If the count is part of the object then you have an inherent problem if one thread can be trying to increase the reference count whilst another is trying to remove the last reference. There needs to be an extra value on the ref count for each globally accessible pointer to the object, so you can always safely increase the ref count if you've got a pointer.

    One option would be to use boost::shared_ptr (see the docs). You can use the free functions atomic_load, atomic_store, atomic_exchange and atomic_compare_exchange (which are conspicuously absent from the docs) to ensure suitable protection when accessing global pointers to shared objects. Once your thread has got a shared_ptr referring to a particular object you can use the normal non-atomic functions to access it.

    Another option is to use Joe Seigh's atomic ref-counted pointer from his atomic_ptr_plus project

  • thinking about your issue a little... what you're saying is that you have 1 object (if the refcount is 1) and yet 2 threads both call delete() on it. I think this is where your problem truly lies.

    The other way round this issue, if you want a threaded object you can safely reuse between threads, is to check that the refcount is greater than 1 before freeing internal memory. Currently you free it and then check whether the refcount is 0.

    From gbjbaanb
  • This isn't an answer, but just a bit of advice. In a situation like this, before you start fixing anything, please make sure you can reliably duplicate these problems. Sometimes this is a simple as running your unit tests in a loop for a while. Sometimes putting some clever Sleeps into your program to force race conditions is helpful.

    Ref counting problems tend to linger, so an investment in your test harness will pay off in the long run.

    Ian Hickman : +1 the only real way of solving multi-threaded issues is to make them repeatable.
    From twk

How can I just get the "Year" portion from the output of timespan() in CodeIgniter?

I have a Date of Birth field and trying to use the timespan function to get the age, but returns "28 Years, 2 Months, 2 Weeks, 3 Days, 15 Hours, 16 Minutes".

Any idea how I can just get the "28 Years" part?

Thanks!

  • There are many ways to do this, with the string in $date, like so:

    $date = '28 Years, 2 Months, 2 Weeks, 3 Days, 15 Hours, 16 Minutes';
    
    This will give you "28 Years"
    $yearsPart = substr($date, 0, strpos($date, 'Years') + 5);
    
    So will this:
    $parts = split(', ', $date);
    $yearsPart = $parts[0];
    
    From Kevin Chan
  • I suggest you use PHP's strftime() function. Instead of using the CI's timespan().

    echo strftime('%Y', 1226239392);

C# code from desktop to the web

If I develop a desktop app using C#, and later want to turn it into a webapp but don't want to use ASP.NET, what are my options?

I did a bit of searching and it looks like there doesn't appear to be a good solution to integrate C# code with any scripting language other than running it as a web service and making SOAP calls.

Any other ideas?

  • Why would you make things so difficult for yourself? The best thing would be to put almost all of your code into an assembly, and just use the winforms app for display purposes. Then, later, you can just reimplement the display logic in asp.net.

    So, I guess the answer is no.

  • AJAX + WebService + plain HTML

    From Mote
  • You could embed a webserver in the application. It's quite easy, even with threading so that you can handle simultaneous requests.

    There's a bunch of examples on the web, here's one at the codeplex: http://www.codeplex.com/webserver

  • The reason I don't want to use ASP.NET is that I can't seem to find any decent (ie recommended) VPS hosting and I don't want to go with dedicated hosting right off the gate. Linux hosting is much more plentiful.

    I guess the other thing I could do is use Mono and forget about PHP etc

    Joel Coehoorn : mono is probably your best bet if you already have C# objects you'll want to use.
    Ilya Kochetov : http://maximumasp.com/ are pretty good for .NET hosting
  • It would be easy enough to have your application offering a SOAP service, which you could then integrate with a front-end in pretty much any language.

    If you really want to avoid that then just go for some less recommended but cheap ASP.Net hosting and use that - if the application is a success you can always shift to dedicated hosting later. It's worth spending a bit of money to make your life a whole lot easier and from what you have said there really isn't a lot of point in avoiding ASP.Net if it means you have to do four times as much work.

    From glenatron
  • How about ASP.NET on Mono? How painful is that realistically?

  • I can't leave a comment for your reply about hosting but I've had .net hosting with Lunarpages for ages now and found it to be just about as affordable as linux hosting and with the same perks like php support, unlimited mysql and ms sql dbs etc.

    To answer the mono question, it's fine but I think Mono only supports up to 3.0 ATM.

    From Echostorm
  • I vote monorail. Keep a nice MVC model.

How to detect file ends in newline?

Over at Can you modify text files when committing to subversion? Grant suggested that I block commits instead.

However I don't know how to check a file ends with a newline. How can you detect that the file ends with a newline?

  • You should be able to do it via a SVN pre-commit hook.

    See this example.

  • You could use something like this as your pre-commit script:

    #! /usr/bin/perl
    
    while (<>) {
        $last = $_;
    }
    
    if (! ($last =~ m/\n$/)) {
        print STDERR "File doesn't end with \\n!\n";
        exit 1;
    }
    
    From bstark
  • Using only bash:

    x=`tail -n 1 your_textfile`
    if [ "$x" == "" ]; then echo "empty line"; fi
    

    (Take care to copy the whitespaces correctly!)

    @grom:

    tail does not return an empty line

    Damn. My test file didn't end on \n but on \n\n. Apparently vim can't create files that don't end on \n (?). Anyway, as long as the “get last byte” option works, all's well.

  • @Konrad: tail does not return an empty line. I made a file that has some text that doesn't end in newline and a file that does. Here is the output from tail:

    $ cat test_no_newline.txt
    this file doesn't end in newline$ 
    
    $ cat test_with_newline.txt
    this file ends in newline
    $
    

    Though I found that tail has get last byte option. So I modified your script to:

    #!/bin/sh
    c=`tail -c 1 $1`
    if [ "$c" != "" ]; then echo "no newline"; fi
    
    From grom
  • This answer worked well for me.

    From nwahmaet
  • Or even simpler:

    #!/bin/sh
    test `tail -c 1 $1` && echo "no newline at eof: $1"
    
    From felipec

Does anyone know some cool PL/SQL plugin for IntelliJ Idea?

I've evaluated some plugins from official IntelliJ repository, but none of them seems to provide more then basic syntax highlighting. Even highlighting is limited. For example, Database Navigator doesn't highlight IF. It would be great to have proper highlighting. And if it would have auto-complete feature and provide file structure view I would be completely happy. I use SQL Query Plugin when I need to post some little stuff to database or to query something from it. I use PL/SQL Developer when I need to make more complex things, or when I need to modify PL/SQL. But most of the time I need to navigate through mix of Java, JavaScript and PL/SQL code. Unfortunately, SQL Query Plugin doesn't help with that as well as PL/SQL Developer.

  • Have you tried SQL Query Plugin? It comes with a great host of features, including multiple query windows, direct editing of tables, and of course, proper highlighting for PL/SQL syntax and a browser of the internal database structure.

    It also integrates well with the main editor: you can right-click on any selected Java string containing SQL and "Send to SQLPlugin" to strip out all of the quotes and non-SQL syntax.

    From David

OPTION(MAXDOP 1) in SQL Server

I have never clearly understood the usage of MAXDOP. I know it makes the query faster and thats the last that I can use in Query Optimization. But when and where it is best suited..

Thanks Guys!!!

  • This is a general rambling on Parallelism in SQL Server, it might not answer your question directly.

    From Books Online, on MAXDOP:

    Sets the maximum number of processors the query processor can use to execute a single index statement. Fewer processors may be used depending on the current system workload.

    See Rickie Lee's blog on parallelism and CXPACKET wait type. It's quite interesting.

    Generally, in an OLTP database, my opinion is that if a query is so costly it needs to be executed on several processors, the query needs to be re-written into something more efficient.

    Why you get better results adding MAXDOP(1)? Hard to tell without the actual execution plans, but it might be so simple as that the execution plan is totally different that without the OPTION, for instance using a different index (or more likely) JOINing differently, using MERGE or HASH joins.

  • As Kaboing mentioned, MAXDOP(n) actually controls the number of CPU cores that are being used in the query processor.

    On a completely idle system, SQL Server will attempt to pull the tables into memory as quickly as possible and join between them in memory. It could be that, in your case, it's best to do this with a single CPU. This might have the same effect as using OPTION (FORCE ORDER) which forces the query optimizer to use the order of joins that you have specified. IN some cases, I have seen OPTION (FORCE PLAN) reduce a query from 26 seconds to 1 second of execution time.

    Books Online goes on to say that possible values for MAXDOP are:

    0 - Uses the actual number of available CPUs depending on the current system workload. This is the default value and recommended setting. 1 - Suppresses parallel plan generation. The operation will be executed serially. 2-64 - Limits the number of processors to the specified value. Fewer processors may be used depending on the current workload. If a value larger than the number of available CPUs is specified, the actual number of available CPUs is used.

    I'm not sure what the best usage of MAXDOP is, however I would take a guess and say that if you have a table with 8 partitions on it, you would want to specify MAXDOP(8) due to I/O limitations, but I could be wrong.

    Here are a few quick links I found about MAXDOP:

    Books Online: Degree of Parallelism

    General guidelines to use to configure the MAXDOP option

  • There are a couple of parallization bugs in SQL server with abnormal input. OPTION(MAXDOP 1) will sidestep them.

    Ed Sykes : Could you elaborate on those bugs please?
    Joshua : I was unable to fully qualify the bugs, but one in particular: when a left join was expected to match very few % of rows would try to spool both tables and loop join rather than bookmark lookup only with parallelization on.
    From Joshua
  • As something of an aside, MAXDOP can apparently be used as a workaround to a potentially nasty bug:

    Returned identity values not always correct

    From Paul

Eclipse for IntelliJ Idea Users

I have a coworker who is looking to switch from InteilliJ Idea to Eclipse, and is concerned about not knowing the Eclipse set of commands.

I was wondering - would anyone have a link to keyboard mappings that can set Eclipse commands to at least sort of match Idea?

Have you made this switch? Any "gotchas", tips, or info we should be aware of?

Thanks!

  • Sorry for offtopic and excuse me for that, but what are the reasons for such switch?

    awied : Mostly because the version that we have available is not too current and is reportedly quite slow.
    Bartosz Blimke : Eclipse is much slower.
    From Vugluskr
  • Why would he change from IntelliJ to Eclipse? Unless he is a masochist and wants to change his life into a nightmare. There is a reason why it is easy to find Eclipse mappings for IntelliJ and difficult to find IntelliJ mappings for Eclipse.

  • If he definitely want to do this:

    http://www.jroller.com/ervines/entry/intellij_style_mappings_for_eclipse

  • Get the plugin from here. It seems easier to install than the one in Bartosz' answer, plus no 404s...

    For the lazy: direct link to plugin

    Drop the plugin jar in eclipse/plugins folder and restart eclipse. Now in preferences dialog under General > Keys you can find "Intellij Idea" key scheme.

    From itsadok