There were bugs here and there, but one thing I want to point out: If you are using boost threads and OpenGL, make sure that OpenGL thread is always bound the thread which "talks" with OpenGL. If there are several threads talking to OpenGL, you need to change context between threads by wglMakeCurrent:

Code :
wglMakeCurrent(NULL, NULL);  //leaving thread
 
wglMakeCurrent(Window_Handle/HDC, Rendering_Handle/HGLRC);  //new thread

Context changing is an expensive operation as well as to create and destroy threads. Therefore I'm using boost::asio library which keeps your threads alive, so a single thread invocation and destruction happens during the lifetime of a program. There is one caveat about boost::asio and OpenGL: DON'T USE A THREADPOOL!! If you do that, you're forced to call wglMakeCurrent every time you use your threads. Instead use fixed threads and call wglMakeCurrent only once. Below is an example class how to do that:

Code :
#ifndef __saie_H
#define __saie_H
 
class Saie : public boost::asio::io_service::service {
 
  private:
	boost::asio::io_service ioPalvelu;
	boost::shared_ptr<boost::asio::io_service::work> tyo;
	boost::shared_ptr<boost::thread> saie;
	volatile bool sammutus;
 
	Saie(const Saie& saie);
	Saie & operator=(const Saie& saie);
 
  public:
	Saie(boost::asio::io_service& io);
	virtual ~Saie();
 
//we need to define an abstract method
	void shutdown_service() {}
 
//returns a reference to this service
	boost::asio::io_service& annaPalvelu();
 
//test whether the service is ready
	bool onkoPysaytetty();
 
//run a thread
	void saieRun(void (*funktio)());
 
//stop service
	void saieStop();
 
//restart service
	void saieReset();
};
 
#endif
 
 
 
 
#include "stdafx.h"
 
#include "saie.h"
 
Saie::Saie(boost::asio::io_service& io) : boost::asio::io_service::service(io), 
	                                      ioPalvelu(),
	                                      tyo(new boost::asio::io_service::work(ioPalvelu)), 
                                          saie(new boost::thread(boost::bind(&boost::asio::io_service::run, &ioPalvelu))) {
 
  sammutus=false;
}
 
Saie::~Saie() {
  saieStop();
}
 
 
boost::asio::io_service& Saie::annaPalvelu() {
  return ioPalvelu;
}
 
bool Saie::onkoPysaytetty() {
  return sammutus;
}
 
void Saie::saieRun(void (*funktio)()) {
  ioPalvelu.post(funktio);
}
 
void Saie::saieStop() {
  if (sammutus==false) {
    ioPalvelu.stop();
    if (saie) {
		saie->join();
	}
	sammutus=true;
  }
}
 
void Saie::saieReset() {
  if (sammutus==true) {
	ioPalvelu.reset();
	tyo.reset(new boost::asio::io_service::work(ioPalvelu));
	saie.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, &ioPalvelu)));
	sammutus=false;
  }
}