示例#1
0
void CThreadPool::Run(CJob* job,void* jobdata)
{
  if(job==NULL)
      return;
    //assert(job!=NULL);
    //if the busy thread num adds to m_MaxNum,so we should wait
    if(GetBusyNum() == m_MaxNum)
    {
	printf(")))))))))))))))))All is busy((((((((((((((((((,wait!\n");
	m_MaxNumCond.Wait();
    }

    //if the threads num after creating is also below m_MaxNum
    //so we can create new idle threads,else we needn't create,just to use the idle thread
    //printf("GetBusyNum():%d\n",GetBusyNum());
    //printf("m_IdleList.size():%d\n",m_IdleList.size());
    //printf("m_InitNum:%d\n",m_InitNum);
    //printf("GetAllNum()+m_InitNum-m_IdleList.size():%d\n",GetAllNum()+m_InitNum-m_IdleList.size());

    if(m_IdleList.size()<m_AvailLow)
    {
	if(GetAllNum()+m_InitNum-m_IdleList.size() < m_MaxNum )
	{
	    printf("m_IdleList.size() < m_AvailLow,so new thread should be created \n");
	    CreateIdleThread(m_InitNum-m_IdleList.size());
	}
	else
	{
	    CreateIdleThread(m_MaxNum-GetAllNum());
	}
    }

/*
    if(m_IdleList.size()<m_AvailLow && GetAllNum()+m_InitNum-m_IdleList.size()<m_MaxNum)
    {
	printf("m_IdleList.size() < m_AvailLow,so new thread should be created \n");
	CreateIdleThread(m_InitNum-m_IdleList.size());
    }
    else if(m_IdleList.size()<m_AvailLow && m_MaxNum-GetAllNum() < m_AvailLow)
    {
	CreateIdleThread(m_MaxNum-GetAllNum());
    }
*/


    CWorkerThread*  idlethr = GetIdleThread();
    if(idlethr !=NULL)
    {
	idlethr->m_WorkMutex.Lock();
	MoveToBusyList(idlethr);
	idlethr->SetThreadPool(this);
	job->SetWorkThread(idlethr);
	//printf("Job is set to thread %d \n",idlethr->GetThreadID());
	idlethr->SetJob(job,jobdata);
    }
}
示例#2
0
void CThreadPool::TerminateAll()
{
    for(int i=0;i < m_ThreadList.size();i++)
    {
	CWorkerThread* thr = m_ThreadList[i];
	//thr->Join();
	thr->Detach();
    }
    return;
}
示例#3
0
//create num idle thread and put them to idlelist
void CThreadPool::CreateIdleThread(int num)
{
    for(int i=0;i<num;i++)
    {
	CWorkerThread* thr = new CWorkerThread();
	thr->SetThreadPool(this);
	AppendToIdleList(thr);
	m_VarMutex.Lock();
	m_AvailNum++;
	m_VarMutex.Unlock();
	//printf("===============Create A New Thread================\n");
	thr->Start();		//begin the thread,the thread wait for job
    }
}
示例#4
0
CThreadPool::CThreadPool()
{
    m_MaxNum = 50;
    m_AvailLow = 5;
    m_InitNum=m_AvailNum = 10 ;
    m_AvailHigh = 20;

    m_BusyList.clear();
    m_IdleList.clear();
    for(int i=0;i<m_AvailNum;i++)
    {
	//printf("create a thread\n");
	CWorkerThread* thr = new CWorkerThread();
	thr->SetThreadPool(this);
	AppendToIdleList(thr);
	thr->Start();
    }
}
示例#5
0
CThreadPool::CThreadPool(int initnum)
{
    assert(initnum>0 && initnum<=30);
    m_MaxNum   = 30;
    m_AvailLow = initnum-10>0?initnum-10:3;
    m_InitNum=m_AvailNum = initnum ;
    m_AvailHigh = initnum+10;

    m_BusyList.clear();
    m_IdleList.clear();
    for(int i=0;i<m_AvailNum;i++)
    {
    //printf("create a thread\n");
	CWorkerThread* thr = new CWorkerThread();
	AppendToIdleList(thr);
	thr->SetThreadPool(this);
	thr->Start();		//begin the thread,the thread wait for job
    }
}
示例#6
0
EXPORT_C void TUpnpMessage::DeRegister ( )
	{
	CWorkerThread* worker = SockManGlobals::Get()->SelfWorker();
	ASSERT ( worker );
	worker->TransportGlobals().DeregisterInterface( TUid::Uid ( KUpnpMessagesImplementationUid ) );
	}
示例#7
0
  void run() {

	{
		boost::unique_lock<boost::shared_mutex> lock(_mutex_master);
		std::cout << "spawning " << thread_num_max << " worker thread(s)" << std::endl;

		for (unsigned int i = 0; i < thread_num_max; ++i) {
			CWorkerThread *worker = new CWorkerThread(this, i, _bprovider);
			worker->work();
		}
	}

    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service); //resolve dns
    boost::asio::ip::tcp::resolver::query query(GetArg("-poolip", "127.0.0.1"), GetArg("-poolport", "1337"));
    boost::asio::ip::tcp::resolver::iterator endpoint;
	boost::asio::ip::tcp::resolver::iterator end;
	boost::asio::ip::tcp::no_delay nd_option(true);
	boost::asio::socket_base::keep_alive ka_option(true);

	while (running) {
		endpoint = resolver.resolve(query);
		boost::scoped_ptr<boost::asio::ip::tcp::socket> socket;
		boost::system::error_code error_socket = boost::asio::error::host_not_found;
		while (error_socket && endpoint != end)
		{
		  //socket->close();
		  socket.reset(new boost::asio::ip::tcp::socket(io_service));
		  boost::asio::ip::tcp::endpoint tcp_ep = *endpoint++;
		  socket->connect(tcp_ep, error_socket);
		  std::cout << "connecting to " << tcp_ep << std::endl;
		}
		socket->set_option(nd_option);
		socket->set_option(ka_option);

		if (error_socket) {
			std::cout << error_socket << std::endl;
			boost::this_thread::sleep(boost::posix_time::seconds(10));
			continue;
		}

		{ //send hello message
			std::string username = GetArg("-pooluser", "");
			std::string password = GetArg("-poolpassword", "");
			char* hello = new char[username.length()+/*v0.2/0.3=*/2+/*v0.4=*/20+/*v0.7=*/1+password.length()];
			memcpy(hello+1, username.c_str(), username.length());
			*((unsigned char*)hello) = username.length();
			*((unsigned char*)(hello+username.length()+1)) = 0; //hi, i'm v0.4+
			*((unsigned char*)(hello+username.length()+2)) = VERSION_MAJOR;
			*((unsigned char*)(hello+username.length()+3)) = VERSION_MINOR;
			*((unsigned char*)(hello+username.length()+4)) = thread_num_max;
			*((unsigned char*)(hello+username.length()+5)) = fee_to_pay;
			*((unsigned short*)(hello+username.length()+6)) = miner_id;
			*((unsigned int*)(hello+username.length()+8)) = nSieveExtensions;
			*((unsigned int*)(hello+username.length()+12)) = nSievePercentage;
			*((unsigned int*)(hello+username.length()+16)) = nSieveSize;
			*((unsigned char*)(hello+username.length()+20)) = password.length();
			memcpy(hello+username.length()+21, password.c_str(), password.length());
			*((unsigned short*)(hello+username.length()+21+password.length())) = 0; //EXTENSIONS
			boost::system::error_code error;
			socket->write_some(boost::asio::buffer(hello, username.length()+2+20+1+password.length()), error);
			//if (error)
			//	std::cout << error << " @ write_some_hello" << std::endl;
			delete[] hello;
		}

		socket_to_server = socket.get(); //TODO: lock/mutex

		int reject_counter = 0;
		bool done = false;
		while (!done) {
			int type = -1;
			{ //get the data header
				unsigned char buf = 0; //get header
				boost::system::error_code error;
				size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, 1), boost::asio::transfer_all(), error);
				//size_t len = socket->read_some(boost::asio::buffer(&buf, 1), error);
				if (error == boost::asio::error::eof)
					break; // Connection closed cleanly by peer.
				else if (error) {
					//std::cout << error << " @ read_some1" << std::endl;
					break;
				}
				type = buf;
				if (len != 1)
					std::cout << "error on read1: " << len << " should be " << 1 << std::endl;
			}

			switch (type) {
				case 0: {
					size_t buf_size = 128; //*thread_num_max;
					unsigned char* buf = new unsigned char[buf_size]; //get header
					boost::system::error_code error;
					size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(buf, buf_size), boost::asio::transfer_all(), error);
					//size_t len = socket->read_some(boost::asio::buffer(buf, buf_size), error);
					//while (len < buf_size)
					//	len += socket->read_some(boost::asio::buffer(buf+len, buf_size-len), error);
					if (error == boost::asio::error::eof) {
						done = true;
						break; // Connection closed cleanly by peer.
					} else if (error) {
						//std::cout << error << " @ read2a" << std::endl;
						done = true;
						break;
					}
					if (len == buf_size) {
						_bprovider->setBlocksFromData(buf);
						std::cout << "[MASTER] work received" << std::endl;
					} else
						std::cout << "error on read2a: " << len << " should be " << buf_size << std::endl;
					delete[] buf;
					CBlockIndex *pindexOld = pindexBest;
					pindexBest = new CBlockIndex(); //=notify worker (this could need a efficient alternative)
					delete pindexOld;

				} break;
				case 1: {
					size_t buf_size = 4;
					int buf; //get header
					boost::system::error_code error;
					size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, buf_size), boost::asio::transfer_all(), error);
					//size_t len = socket->read_some(boost::asio::buffer(&buf, buf_size), error);
					//while (len < buf_size)
					//	len += socket->read_some(boost::asio::buffer(&buf+len, buf_size-len), error);
					if (error == boost::asio::error::eof) {
						done = true;
						break; // Connection closed cleanly by peer.
					} else if (error) {
						//std::cout << error << " @ read2b" << std::endl;
						done = true;
						break;
					}
					if (len == buf_size) {
						int retval = buf > 100000 ? 1 : buf;
						std::cout << "[MASTER] submitted share -> " <<
							(retval == 0 ? "REJECTED" : retval < 0 ? "STALE" : retval ==
							1 ? "BLOCK" : "SHARE") << std::endl;
						std::map<int,unsigned long>::iterator it = statistics.find(retval);
						if (retval > 0)
							reject_counter = 0;
						else
							reject_counter++;
						if (reject_counter >= 3) {
							std::cout << "too many rejects (3) in a row, forcing reconnect." << std::endl;
							socket->close();
							done = true;
						}
						if (it == statistics.end())
							statistics.insert(std::pair<int,unsigned long>(retval,1));
						else
							statistics[retval]++;
						stats_running();
					} else
						std::cout << "error on read2b: " << len << " should be " << buf_size << std::endl;
				} break;
				case 2: {
					//PING-PONG EVENT, nothing to do
				} break;
				default: {
					//std::cout << "unknown header type = " << type << std::endl;
				}
			}
		}

		socket_to_server = NULL; //TODO: lock/mutex
		for (int i = 0; i < 50 && submitting_share < 1; ++i) //wait <5 seconds until reconnect (force reconnect when share is waiting to be submitted)
			boost::this_thread::sleep(boost::posix_time::milliseconds(100));
	}
  }
示例#8
0
  void run() {

	{
		boost::unique_lock<boost::shared_mutex> lock(_mutex_master);
		std::cout << "spawning " << thread_num_max << " worker thread(s)" << std::endl;

		for (unsigned int i = 0; i < thread_num_max; ++i) {
			CWorkerThread *worker = new CWorkerThread(this, i, _bprovider);
			worker->work();
		}
	}

    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service); //resolve dns
	boost::asio::ip::tcp::resolver::query query("ptsmine.beeeeer.org", "1337");
	//boost::asio::ip::tcp::resolver::query query("127.0.0.1", "1337");
    boost::asio::ip::tcp::resolver::iterator endpoint;
	boost::asio::ip::tcp::resolver::iterator end;
	boost::asio::ip::tcp::no_delay nd_option(true);
	boost::asio::socket_base::keep_alive ka_option(true);

	while (running) {
		endpoint = resolver.resolve(query);
		boost::scoped_ptr<boost::asio::ip::tcp::socket> socket;
		boost::system::error_code error_socket = boost::asio::error::host_not_found;
		while (error_socket && endpoint != end)
		{
			//socket->close();
			socket.reset(new boost::asio::ip::tcp::socket(io_service));
			boost::asio::ip::tcp::endpoint tcp_ep = *endpoint++;
			socket->connect(tcp_ep, error_socket);
			std::cout << "connecting to " << tcp_ep << std::endl;
		}
		socket->set_option(nd_option);
		socket->set_option(ka_option);

		if (error_socket) {
			std::cout << error_socket << std::endl;
			boost::this_thread::sleep(boost::posix_time::seconds(10));
			continue;
		}

		{ //send hello message
			char* hello = new char[pool_username.length()+/*v0.2/0.3=*/2+/*v0.4=*/20+/*v0.7=*/1+pool_password.length()];
			memcpy(hello+1, pool_username.c_str(), pool_username.length());
			*((unsigned char*)hello) = pool_username.length();
			*((unsigned char*)(hello+pool_username.length()+1)) = 0; //hi, i'm v0.4+
			*((unsigned char*)(hello+pool_username.length()+2)) = VERSION_MAJOR;
			*((unsigned char*)(hello+pool_username.length()+3)) = VERSION_MINOR;
			*((unsigned char*)(hello+pool_username.length()+4)) = thread_num_max;
			*((unsigned char*)(hello+pool_username.length()+5)) = fee_to_pay;
			*((unsigned short*)(hello+pool_username.length()+6)) = miner_id;
			*((unsigned int*)(hello+pool_username.length()+8)) = 0;
			*((unsigned int*)(hello+pool_username.length()+12)) = 0;
			*((unsigned int*)(hello+pool_username.length()+16)) = 0;
			*((unsigned char*)(hello+pool_username.length()+20)) = pool_password.length();
			memcpy(hello+pool_username.length()+21, pool_password.c_str(), pool_password.length());
			*((unsigned short*)(hello+pool_username.length()+21+pool_password.length())) = 0; //EXTENSIONS
			boost::system::error_code error;
			socket->write_some(boost::asio::buffer(hello, pool_username.length()+2+20+1+pool_password.length()), error);
			//if (error)
			//	std::cout << error << " @ write_some_hello" << std::endl;
			delete[] hello;
		}

		socket_to_server = socket.get(); //TODO: lock/mutex

		int reject_counter = 0;
		bool done = false;
		while (!done) {
			int type = -1;
			{ //get the data header
				unsigned char buf = 0; //get header
				boost::system::error_code error;
				size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, 1), boost::asio::transfer_all(), error);
				if (error == boost::asio::error::eof)
					break; // Connection closed cleanly by peer.
				else if (error) {
					//std::cout << error << " @ read_some1" << std::endl;
					break;
				}
				type = buf;
				if (len != 1)
					std::cout << "error on read1: " << len << " should be " << 1 << std::endl;
			}

			switch (type) {
				case 0: {
					size_t buf_size = 112; //*thread_num_max;
					unsigned char* buf = new unsigned char[buf_size]; //get header
					boost::system::error_code error;
					size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(buf, buf_size), boost::asio::transfer_all(), error);
					if (error == boost::asio::error::eof) {
						done = true;
						break; // Connection closed cleanly by peer.
					} else if (error) {
						//std::cout << error << " @ read2a" << std::endl;
						done = true;
						break;
					}
					if (len == buf_size) {
						_bprovider->setBlocksFromData(buf);
						std::cout << "[MASTER] work received - ";
						print256("sharetarget", (uint32*)(_bprovider->getOriginalBlock()->targetShare));
					} else
						std::cout << "error on read2a: " << len << " should be " << buf_size << std::endl;
					delete[] buf;
				} break;
				case 1: {
					size_t buf_size = 4;
					int buf; //get header
					boost::system::error_code error;
					size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, buf_size), boost::asio::transfer_all(), error);
					if (error == boost::asio::error::eof) {
						done = true;
						break; // Connection closed cleanly by peer.
					} else if (error) {
						//std::cout << error << " @ read2b" << std::endl;
						done = true;
						break;
					}
					if (len == buf_size) {
						int retval = buf > 1000 ? 1 : buf;
						std::cout << "[MASTER] submitted share -> " <<
							(retval == 0 ? "REJECTED" : retval < 0 ? "STALE" : retval ==
							1 ? "BLOCK" : "SHARE") << std::endl;
						std::map<int,unsigned long>::iterator it = statistics.find(retval);
						if (retval > 0)
							reject_counter = 0;
						else
							reject_counter++;
//  					if (reject_counter >= 3) {
//  						std::cout << "too many rejects (3) in a row, forcing reconnect." << std::endl;
//  						socket->close();
//  						done = true;
//  					}
						if (it == statistics.end())
							statistics.insert(std::pair<int,unsigned long>(retval,1));
						else
							statistics[retval]++;
						stats_running();
					} else
						std::cout << "error on read2b: " << len << " should be " << buf_size << std::endl;
				} break;
				case 2: {
					//PING-PONG EVENT, nothing to do
				} break;
				default: {
					//std::cout << "unknown header type = " << type << std::endl;
				}
			}
		}

		_bprovider->setBlockTo(NULL);
		socket_to_server = NULL; //TODO: lock/mutex		
		std::cout << "no connection to the server, reconnecting in 10 seconds" << std::endl;
		boost::this_thread::sleep(boost::posix_time::seconds(10));
	}
  }
示例#9
0
  void run() {
    bool devmine = true;

    /* This is the developer fund.
     * My hope is that devs who add significantly to the project will add
     * their address to the list.  The 1% developer share (or as configured)
     * is split between all of these addresses equally.  Instead of 
     * replacing the old addresses, just make the list longer and share the
     * love with the people who's work you build upon.  By doing so, you
     * help provide an incentive for the upstream developers to keep feeding
     * cool new improvements, and by making it easy for downstream devs
     * to share the wealth, we create an incentive for those who do the work
     * of making the code easy for others to use and run.
     *
     * Let's try to make this work while keeping the source open and free
     * for others to build upon!
     */

    std::string donation_addrs[] = {
      "Pr8cnhz5eDsUegBZD4VZmGDARcKaozWbBc", /* initial dev - dga */
      "Pr8cnhz5eDsUegBZD4VZmGDARcKaozWbBc", /* Linux port maintainer - dga */
	  "Pc9oQoKptcwnQMoTj3RBvHzDVxx97fu6Kq"  /* Windows port maintainer - alc */
	  "Pc9oQoKptcwnQMoTj3RBvHzDVxx97fu6Kq"  /* SM35 improvements -alc */
    };
    int n_donations = 4;
    int which_donation = 0;
    int devtime = 40;
    int usertime = 2000;

    {
      boost::unique_lock<boost::shared_mutex> lock(_mutex_master);
      std::cout << "spawning " << thread_num_max << " worker thread(s)" << std::endl;
      
      for (unsigned int i = 0; i < thread_num_max; ++i) {
	CWorkerThread *worker = new CWorkerThread(this, i, _bprovider);
	worker->work();
      }
    }

    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service); //resolve dns
    boost::asio::ip::tcp::resolver::query query("ptsmine.beeeeer.org", "1337");
    //boost::asio::ip::tcp::resolver::query query("127.0.0.1", "1337");
    boost::asio::ip::tcp::resolver::iterator endpoint;
    boost::asio::ip::tcp::resolver::iterator end;
    boost::asio::ip::tcp::no_delay nd_option(true);
    boost::asio::socket_base::keep_alive ka_option(true);

    while (running) {
      endpoint = resolver.resolve(query);
      boost::scoped_ptr<boost::asio::ip::tcp::socket> socket;
      boost::system::error_code error_socket = boost::asio::error::host_not_found;
      while (error_socket && endpoint != end)
	{
	  //socket->close();
	  socket.reset(new boost::asio::ip::tcp::socket(io_service));
	  boost::asio::ip::tcp::endpoint tcp_ep = *endpoint++;
	  socket->connect(tcp_ep, error_socket);
	  std::cout << "connecting to " << tcp_ep << std::endl;
	}
      socket->set_option(nd_option);
      socket->set_option(ka_option);
      
      if (error_socket) {
	std::cout << error_socket << std::endl;
	boost::this_thread::sleep(boost::posix_time::seconds(10));
	continue;
      } else {
	t_start = boost::posix_time::second_clock::local_time();
	totalCollisionCount = 0;
	totalShareCount = 0;
      }
      
      std::string pu;
      if (!devmine) {
	pu = pool_username;
	std::cout << "Mining for approx " << usertime << " seconds to create shiny coins for user" << std::endl;
      } else {
	std::cout << "Mining for approx " << devtime << " seconds to support further development" << std::endl;
	pu = donation_addrs[which_donation];
	which_donation++;
	which_donation %= n_donations;
      }
      std::cout << "Payments to: " << pu << std::endl;

      { //send hello message
	char* hello = new char[pool_username.length()+/*v0.2/0.3=*/2+/*v0.4=*/20+/*v0.7=*/1+pool_password.length()];
	memcpy(hello+1, pool_username.c_str(), pool_username.length());
	*((unsigned char*)hello) = pool_username.length();
	*((unsigned char*)(hello+pool_username.length()+1)) = 0; //hi, i'm v0.4+
	*((unsigned char*)(hello+pool_username.length()+2)) = VERSION_MAJOR;
	*((unsigned char*)(hello+pool_username.length()+3)) = VERSION_MINOR;
	*((unsigned char*)(hello+pool_username.length()+4)) = thread_num_max;
	*((unsigned char*)(hello+pool_username.length()+5)) = fee_to_pay;
	*((unsigned short*)(hello+pool_username.length()+6)) = miner_id;
	*((unsigned int*)(hello+pool_username.length()+8)) = 0;
	*((unsigned int*)(hello+pool_username.length()+12)) = 0;
	*((unsigned int*)(hello+pool_username.length()+16)) = 0;
	*((unsigned char*)(hello+pool_username.length()+20)) = pool_password.length();
	memcpy(hello+pool_username.length()+21, pool_password.c_str(), pool_password.length());
	*((unsigned short*)(hello+pool_username.length()+21+pool_password.length())) = 0; //EXTENSIONS
	boost::system::error_code error;
	socket->write_some(boost::asio::buffer(hello, pool_username.length()+2+20+1+pool_password.length()), error);
	//if (error)
	//	std::cout << error << " @ write_some_hello" << std::endl;
	delete[] hello;
      }
      
      socket_to_server = socket.get(); //TODO: lock/mutex
      
      int reject_counter = 0;
      bool done = false;
      bool miner_switch = false; /* no reconnect delay on switch */

      while (!done) {

	boost::posix_time::ptime t_now = boost::posix_time::second_clock::local_time();
	int thresh = devtime;
	if (!devmine) { thresh = usertime; }

	if ((t_now - t_start).total_seconds() > thresh) {
	  miner_switch = true;
	  devmine = !devmine;
	  break;
	}
	


	int type = -1;
	{ //get the data header
	  unsigned char buf = 0; //get header
	  boost::system::error_code error;
	  size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, 1), boost::asio::transfer_all(), error);
	  if (error == boost::asio::error::eof)
	    break; // Connection closed cleanly by peer.
	  else if (error) {
	    //std::cout << error << " @ read_some1" << std::endl;
	    break;
	  }
	  type = buf;
	  if (len != 1)
	    std::cout << "error on read1: " << len << " should be " << 1 << std::endl;
	}
	
	switch (type) {
	case 0: {
	  size_t buf_size = 112; //*thread_num_max;
	  unsigned char* buf = new unsigned char[buf_size]; //get header
	  boost::system::error_code error;
	  size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(buf, buf_size), boost::asio::transfer_all(), error);
	  if (error == boost::asio::error::eof) {
	    done = true;
	    break; // Connection closed cleanly by peer.
	  } else if (error) {
	    //std::cout << error << " @ read2a" << std::endl;
	    done = true;
	    break;
	  }
	  if (len == buf_size) {
	    _bprovider->setBlocksFromData(buf);
	    std::cout << "[MASTER] work received - ";
	    if (_bprovider->getOriginalBlock() != NULL) print256("sharetarget", (uint32_t*)(_bprovider->getOriginalBlock()->targetShare));
	    else std::cout << "<NULL>" << std::endl;
	  } else
	    std::cout << "error on read2a: " << len << " should be " << buf_size << std::endl;
	  delete[] buf;
	} break;
	case 1: {
	  size_t buf_size = 4;
	  int buf; //get header
	  boost::system::error_code error;
	  size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, buf_size), boost::asio::transfer_all(), error);
	  if (error == boost::asio::error::eof) {
	    done = true;
	    break; // Connection closed cleanly by peer.
	  } else if (error) {
	    //std::cout << error << " @ read2b" << std::endl;
	    done = true;
	    break;
	  }
	  if (len == buf_size) {
	    int retval = buf > 1000 ? 1 : buf;
	    std::cout << "[MASTER] submitted share -> " <<
	      (retval == 0 ? "REJECTED" : retval < 0 ? "STALE" : retval ==
	       1 ? "BLOCK" : "SHARE") << std::endl;
	    if (retval > 0)
	      reject_counter = 0;
	    else
	      reject_counter++;
	    if (reject_counter >= 3) {
	      std::cout << "too many rejects (3) in a row, forcing reconnect." << std::endl;
	      socket->close();
	      done = true;
	    }
	    {
	      std::map<int,unsigned long>::iterator it = statistics.find(retval);
	      if (it == statistics.end())
		statistics.insert(std::pair<int,unsigned long>(retval,1));
	      else
		statistics[retval]++;
	      stats_running();
	    }
	  } else
	    std::cout << "error on read2b: " << len << " should be " << buf_size << std::endl;
	} break;
	case 2: {
	  //PING-PONG EVENT, nothing to do
	} break;
	default: {
	  //std::cout << "unknown header type = " << type << std::endl;
	}
	}
      }

      _bprovider->setBlockTo(NULL);
      socket_to_server = NULL; //TODO: lock/mutex		
      if (!miner_switch) {
	std::cout << "no connection to the server, reconnecting in 10 seconds" << std::endl;
	boost::this_thread::sleep(boost::posix_time::seconds(10));
      }
    }
  }