示例#1
0
文件: main.cpp 项目: s-alexander/UPGM
int main (int argc, char *argv[])
{
	payguide::time_start=time(NULL);
	int Ppid=CheckIfPayguideAlreadyUp();
	if (Ppid==0)
	{
		if (MakeLockFile()!=0)
		{
			std::cout << "Error while creating lock file. Can't write /tmp/payguide.lock" << std::endl;
			LogWrite(LOGMSG_CRITICAL, "Error while creating lock file. Can't write /tmp/payguide.lock");
		}
	}
	else
	{
		
		char msg[512];
		snprintf(msg, 511,"Error: payguide already running as process %i. Balling out.", Ppid);
		std::cout << msg << std::endl;
		LogWrite(LOGMSG_CRITICAL, msg);
		exit(0);
	}
	
	PayguideInit();
	WorkInit();
	bool work_init_already=true;
	
	bonbon::BonbonInit();
	
	
	PerlInit(argv[0], payguide::perl_module.c_str());
	payguide::data_conventor.Init();
	for (EVER)
	{
		std::cout << "Running xml paycheck..." << std::endl;
	        const char *main_config_file="/etc/payguide.cfg";
	        paycheck::CPaycheckCore paycheck_core;
	        paycheck_core.LoadConfig(main_config_file);
	        paycheck::CServer server_code;
	        bonbon::CJobManager in_manager;
	        std::vector <paycheck::CSocket *> connections_store;
	        paycheck::CPaycheckThreadParam params(&in_manager, &connections_store, &paycheck_core);
	        bonbon::CThread xml_server1(server_code, params);
	        payguide::xml_paycheck_core=&paycheck_core;

		payguide::quit=false;
		if (!work_init_already)
			WorkInit();
		int sleep_count=0;
		timespec req;
		req.tv_sec=0;
		req.tv_nsec=50000000;
		
		
		payguide::working=true;
		
		LogWrite(LOGMSG_SYSTEM, "Payguide server started sucessful and ready for a work");
		
		/* Ok, lets rock */
		
		SPay *new_pay=NULL;
		sem_wait(&payguide::shutdown_lock);
		bool working_state=payguide::working;
		sem_post(&payguide::shutdown_lock);
		
		printf("TESTING printf(): if you see that in log - world gone mad\n");
		std::cout << "TESTING std::cout: if you see that in log - world gone mad" << std::endl;
		
		while (working_state)
		{
			sem_wait(&payguide::shutdown_lock);
			working_state=payguide::working;
			sem_post(&payguide::shutdown_lock);

			/* Get next pay from DB */
			if (new_pay==NULL)
			{
				new_pay=paycheck_core.XMLGetNextPay();
				if (new_pay==NULL)
				{
					new_pay=PCGetNextPay();
				
					if (new_pay==NULL)
					{
						//printf("get new pay from DB\n");
						if (sleep_count==1)
							new_pay=DBGetNextPay();
					}
					else if (new_pay->test==NO_TEST)
					{
						LogWrite(LOGMSG_CRITICAL, "Payguide received from BIN PAYCHECK (payd) must be marked as testing. Shutdown.");
						char tmp[1024];
						snprintf(tmp, 1024, "Pay params: id/session=[%lli] terminal=[%lli] operator=%i", new_pay->id, new_pay->terminal_id, new_pay->provider_id); 
						LogWrite(LOGMSG_CRITICAL, tmp);
						exit(-1);
					}
				}
				else if (new_pay->test==NO_TEST)
				{
					LogWrite(LOGMSG_CRITICAL, "Payguide received from XML PAYCHECK must be marked as testing. Shutdown.");
					char tmp[1024];
					snprintf(tmp, 1024, "Pay params: id/session=[%lli] terminal=[%lli] operator=%i", new_pay->id, new_pay->terminal_id, new_pay->provider_id); 
					LogWrite(LOGMSG_CRITICAL, tmp);
					exit(-1);
				}
			}

			if (new_pay!=NULL)
			{
//				char logmsg[101]; snprintf(logmsg, 100,"Working on pay %lli", new_pay->id); SendLogMessages(0, logmsg);
				sem_wait(&payguide::free_workers_lock);
				//printf("lock catched\n");
				/* If were is no free worker - find one or create new. */
				if (payguide::free_worker==NULL)
					SetFreeWorker(NULL);
				
				/* If it's ok - init free worker with a new pay */
				if (payguide::free_worker!=NULL)
				{
					LaunchNewPay(new_pay);
					new_pay=NULL;
					sem_post(&payguide::free_workers_lock);	
				}
				
				/* We can't create a new worker - threads limit hit. */
				else
				{
					//LogWrite(LOGMSG_WARNING, "Threads limit hit. Payguide server is overloaded.");
					sem_post(&payguide::free_workers_lock);
					
					if (sleep_count==20)
					{
						ReloadConfigIfImportant();
						ManagerEx();
						sleep_count=0;
						
					}

					nanosleep(&req, NULL);sleep_count++;
					StatisticTick(0.2);

					
				}
			}
			
			/* No new pays, sleep (nojobs_sleep_time) sec*/
			else
			{
				
				/* Manage inactive workers */
				if (sleep_count==20)
				{
					ReloadConfigIfImportant();
					ManagerEx();
					sleep_count=0;
				}
//				sleep(SLEEP_TIME); sleep_count=20;
				nanosleep(&req, NULL);sleep_count++;
				StatisticTick(0.2);

			}
		}
		
		/* Waiting for all workers, or even cancel all pays if force_quit is 1 ... */
		LogWrite(LOGMSG_SYSTEM, "Waiting for all active pays to end - for safe exit - you had to specify right timeouts in your modules.");
		WaitForAllPaysToFinish(force_quit);
		
		/* If it's not reboot - exit */
		sem_wait(&payguide::shutdown_lock);
		bool quit_state=payguide::quit;
		sem_post(&payguide::shutdown_lock);
		if (quit_state)
		{
			LogWrite(LOGMSG_SYSTEM, "Payguide server shutdown normally.");
			LogWrite(LOGMSG_SYSTEM, "Bye-bye!");
			
			/* Stop connection with MySQL database */
			DBShutdown();
		
			/* Stop control server. */
			//CtlServerStop();
			
			mysql_library_end();
			
			if (ossl_lock!=NULL)
				delete [] ossl_lock;
			if (pc_init_result==0)
				PCShutdown();
			/* CleanUp will be automatically called by atexit() function */
			if (RemoveLockFile()!=0)
			{
				std::cout << "Can't remove /tmp/payguide.lock. File doesn't exist or maybe you should delete it manually."  << std::endl;
				LogWrite(LOGMSG_CRITICAL, "Can't remove /tmp/payguide.lock. File doesn't exist or maybe you should delete it manually.");
			}
			OperatorsShutdown();
			EVP_cleanup();
			payguide::data_conventor.Clean();
			PerlShutdown();
			printf("destroying queue\n");
			in_manager.Destroy();
			printf("done\n");
			exit (0);
		}
		
		/* Stop connection with MySQL database */
		DBShutdown();
		
		printf("destroying queue\n");
		in_manager.Destroy();
		printf("done\n");
	        server_code.Kill();
		LogWrite(LOGMSG_SYSTEM, "Rebooting...");
		work_init_already=false;
		CleanUp();
	}
	return 0;
}
示例#2
0
文件: stream.cpp 项目: IcaroL2ORK/pd
/*! Thread worker - fill the fifo with socket data */
void Stream::Work()
{
	int waittime = 0;

	// lower thread priority
    {
	    struct sched_param parm;
	    int policy;
	    if(pthread_getschedparam(pthread_self(),&policy,&parm) >= 0) {
            int minprio = sched_get_priority_min(policy);

            if(debug) post("priority was %i (min = %i)",parm.sched_priority,minprio);

            parm.sched_priority += THRPRIOR;

    		if(parm.sched_priority < minprio) parm.sched_priority = minprio;
            pthread_setschedparam(pthread_self(),policy,&parm);
        }

	    if(pthread_getschedparam(pthread_self(),&policy,&parm) >= 0) {
            if(debug) post("priority set to %i",parm.sched_priority);
        }
    }

	while(!exit) {
		pthread_mutex_lock(&mutex);

		bool wait = true;

		if(!hostname.length() || !mountpt.length() || port < 0) {}
		else
		if(state == ST_INIT || state == ST_RECONNECT) {
			// initialize!

			bool ok = true;

			try {
				file = Connect( hostname.c_str(),mountpt.c_str(),port);
			}
			catch(char *str) {
				if(state != ST_RECONNECT) post(str);
				ok = false;
			}
			catch(...) {
				post("Unknown error while connecting");
				ok = false;
			}

			// initialize decoder
			if(ok) ok = WorkInit();

			// try to fill buffer
			if(ok) {
				int i,lim = (int)(encoded.Size()*encthresh);
				for(i = MAXINITTRIES; i > 0 && encoded.Have() < lim; ) {
					int n = ReadChunk(encoded.Free(),true);
					if(!n) --i;
				}
				if(!i) ok = false;
			}

			if(!ok) {
				Reset();

				if(state == ST_INIT) state = ST_IDLE;
				// if reconnecting keep on doing that...
			}
			else {
				state = ST_PROCESS;
				waittime = 0;
			}
		}
		else if(isOk()) {
			SOCKET fd = file;
			int chunk = encoded.Free();
			if(chunk > encchunk) chunk = encchunk;
			
			if(chunk) {
				int n = ReadChunk(chunk,true);

				if(n == 0) {
					if(debug) post("error receiving data");
					state = ST_WAIT;
				}
				else
					// reset error state
					state = ST_PROCESS;
			}

			if(encoded.Have() < encoded.Size()*encthresh) 
				// immediately get the next chunk
				wait = false;
		}

		if(debug && encoded.Free()) {
			post("fifo: sz/fill = %5i/%3.0f%%",encoded.Size(),(float)encoded.Have()/encoded.Size()*100);
		}

		if(state == ST_WAIT) {
			if(debug) post("Wait for data");
			Sleep(waitgrain);
			waittime += waitgrain;
			if(waittime > waitreconnect) {
				if(debug) post("do reconnect");
				state = ST_RECONNECT;
			}
			wait = false;
		}
		else if(state == ST_RECONNECT) {
			if(debug) post("Reconnecting again");
			Sleep(waitgrain);
			wait = false;
		}


		if(wait) pthread_cond_wait(&cond,&mutex);

		pthread_mutex_unlock(&mutex);
	}

	state = ST_FINISHED;
}