dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7

Thread: Singleton implementation question

  1. #1
    Join Date
    Jan 2009
    Posts
    1,689

    Singleton implementation question

    On the advice on Lindley, I created a singleton to control access to a pointer that doesn't get initialized at the right time, but it's been a while since I've done C++ I'm worried I may not have done it correctly. Is what I did both correct and thread-safe? Ignore the stuff at the beginning of the code and the signature of main, it's just for testing.

    Code:
    #include <iostream>
    
    //These don't affect the functionality for testing, and are implemented corretly in real library
    #define mallocer_t void*  //actually a callback to a void*(size_t) method
    void * global_mutex;  //usually pthread_mutex_t
    struct auto_lock {  //locks a mutex
    public:
    	auto_lock(void*){};
    };
    
    
    
    //singleton class for callback pointers
    template <typename T> class singleton {
    public:
    	inline singleton(){
    		ptr = NULL;
    	}
    	static inline T get(void){ 
    		auto_lock lock(global_mutex);
    		return get_singleton() -> ptr; 
    	}
    	static inline void set(T p){ 
    		auto_lock lock(global_mutex);
    		get_singleton() -> ptr = p; 
    	}
    private:
    	static inline singleton * get_singleton(void){
    		//multi-threaded library, is this okay with the locks?
    		static singleton<T> instance;
    		return &instance;
    	}
    	T ptr;
    };
    
    int main(){
    	std::cout << singleton<mallocer_t>::get() << std::endl;
    	singleton<mallocer_t>::set((void*)0xDEADBEEF);
    	std::cout << singleton<mallocer_t>::get() << std::endl;
    }
    Last edited by ninja9578; July 14th, 2011 at 10:57 AM.

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Singleton implementation question

    Normally, the get_singleton (or getInstance()) method is static public, and the constructor is private. The copy constructor and operator= should also be disabled (declared private, not defined).

    However, for your purposes in the other thread, this may be overkill. One simple way to make a "singleton" is just to do this:

    Header file:
    Code:
    MyClass& getMyClass();
    Source file:
    Code:
    MyClass& getMyClass()
    {
        static MyClass instance;
        return instance;
    }
    I think this is thread-safe in C++0x. It may not be in earlier standards, but all you need to do to work around that is ensure the function is called at least once before any threads are spawned.

  3. #3
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,173

    Re: Singleton implementation question

    Also, no need to make global_mutex global, just make it a private instance of the singleton class.

    In fact, when working with multithreading, avoid global variables of any kind.

  4. #4
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Singleton implementation question

    Yeah, I never worry about making it non-copyable in tests, I've added that. Actually, I don't want to be able to get the singleton at all, just what's stored inside of it, so I also made the ctor private.

    I took the lock out, it shouldn't be used outside of a critical section anyway

    Code:
    template <typename T> class singleton {
    public:
    	static inline T get(void){ 
    		return get_singleton() -> ptr; 
    	}
    	static inline void set(T p){ 
    		get_singleton() -> ptr = p; 
    	}
    private:
    	inline singleton(){ ptr = NULL; }
    	singleton(const singleton<T> &);
    	singleton<T> operator = (const singleton<T> &);
    	static inline singleton<T> * get_singleton(void){
    		static singleton<T> instance;
    		return &instance;
    	}
    	T ptr;
    };
    Last edited by ninja9578; July 14th, 2011 at 01:32 PM.

  5. #5
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,173

    Re: Singleton implementation question

    Quote Originally Posted by ninja9578 View Post
    global_mutex gets used for other things as well, so I can't make it local to the singleton.
    There are two main areas that make multithreading difficult.
    1) Forgetting to release locks
    2) Accessing synch primitives throughout the code

    You've got the first one covered because you are using the RAII auto_lock class.

    To handle the second issue, strive to encapsulate synchronization inside classes as much as possible. When you have different classes, methods, etc. trying to lock and release global synchronization variables, it leads to difficult to track down m/t bugs.

    Use a class member mutex (actually use a critical section) to guard the singleton during access and creation.

    Use another lock inside the singleton class for other locking operations.

    Try to design your classes such that synchronization occurs inside the class as much as possible. That way, users of the class need not worry about the details of thread synchronization (nor do they need to know if it occurs).

  6. #6
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Singleton implementation question

    Thanks for that. That is how I usually try to code. The problem is that this code is old, and feature creep has started to make it really hard to maintain. I plan on doing a rewrite shortly, but in the mean time I gotta deal with it.

  7. #7
    Join Date
    May 2009
    Posts
    2,413

    Re: Singleton implementation question

    Quote Originally Posted by ninja9578 View Post
    On the advice on Lindley, I created a singleton
    Search the net for Meyers Singleton.
    Last edited by nuzzle; July 17th, 2011 at 12:50 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)