Example #1
0
/*
 * TODO: Some form of conformance check so that only packets
 * destined to the particular Ethernet protocol are being captured
 * by the handler... right now.. this might capture other packets as well.
 */
void* fromEthernetDev(void *arg)
{
	interface_t *iface = (interface_t *) arg;
	interface_array_t *iarr = (interface_array_t *)iface->iarray;
	uchar bcast_mac[] = MAC_BCAST_ADDR;

	gpacket_t *in_pkt;

	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);		// die as soon as cancelled
	while (1)
	{
		verbose(2, "[fromEthernetDev]:: Receiving a packet ...");
		if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL)
		{
			fatal("[fromEthernetDev]:: unable to allocate memory for packet.. ");
			return NULL;
		}

		bzero(in_pkt, sizeof(gpacket_t));
		vpl_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t));
		pthread_testcancel();


		//FOR OSPF
		/*
		char tmpbuf[MAX_TMPBUF_LEN];
		uchar valMac1[6];
		uchar valMac2[6];
		uchar valMac3[6];
		char *test1 = "33:33:00:00:00:16";
		char *test2 = "33:33:00:00:00:02";
		char *test3 = "33:33:ff:00:00:04";
		Colon2MAC(test1, valMac1);
		Colon2MAC(test2, valMac2);
		Colon2MAC(test3, valMac3);
		if(COMPARE_MAC(in_pkt->data.header.dst, valMac1) == 0 || 
			COMPARE_MAC(in_pkt->data.header.dst, valMac2) == 0|| 
			COMPARE_MAC(in_pkt->data.header.dst, valMac3) == 0){

			uchar link_ip[4];
			COPY_IP(link_ip,  iface->ip_addr);
			link_ip[0] = IP_ZERO_PREFIX;
			printf("Received IPV6 ICMP bcast from : %s \n", IP2Dot(tmpbuf, link_ip));
			//Then we know that this packet comes from a stub network
			//Set stub bit in neighbour table to true
			//printGPacket(in_pkt, 3, "IP_ROUTINE");
			int index = findNeighbourIndex(link_ip);

			if(index == -1)
			{
				// Add to neighbour table
				addNeighbourEntry(iface->ip_addr, link_ip, iface->interface_id);

				// Add to graph
				addStubToGraph(findNeighbourIndex(link_ip));

				updateRoutingTable();
				//printf("BCASTING my new stub neighbour\n");
				//bcast this change
				OSPFSendLSA();
			}

			setStubToTrueFlag(link_ip);
			
			
		}
		*/
		
		// check whether the incoming packet is a layer 2 broadcast or
		// meant for this node... otherwise should be thrown..
		// TODO: fix for promiscuous mode packet snooping.
		if ((COMPARE_MAC(in_pkt->data.header.dst, iface->mac_addr) != 0) &&
			(COMPARE_MAC(in_pkt->data.header.dst, bcast_mac) != 0))
		{
			verbose(1, "[fromEthernetDev]:: Packet dropped .. not for this router!? ");
			free(in_pkt);
			continue;
		}

		// copy fields into the message from the packet..
		in_pkt->frame.src_interface = iface->interface_id;
		COPY_MAC(in_pkt->frame.src_hw_addr, iface->mac_addr);
		COPY_IP(in_pkt->frame.src_ip_addr, iface->ip_addr);

		//calculate Input rate
		if(start == 1){
			counter_in = counter_in+sizeof(gpacket_t);
		}

		// check for filtering.. if the it should be filtered.. then drop
		if (filteredPacket(filter, in_pkt))
		{
			verbose(2, "[fromEthernetDev]:: Packet filtered..!");
			free(in_pkt);
			continue;   // skip the rest of the loop
		}

		verbose(2, "[fromEthernetDev]:: Packet is sent for enqueuing..");
		enqueuePacket(pcore, in_pkt, sizeof(gpacket_t));
	}
}
Example #2
0
void *pluginsd_main(void *ptr)
{
	if(ptr) { ; }

	info("PLUGINS.D thread created with task id %d", gettid());

	if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
		error("Cannot set pthread cancel type to DEFERRED.");

	if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
		error("Cannot set pthread cancel state to ENABLE.");

	char *dir_name = config_get("plugins", "plugins directory", PLUGINS_DIR);
	int automatic_run = config_get_boolean("plugins", "enable running new plugins", 1);
	int scan_frequency = (int) config_get_number("plugins", "check for new plugins every", 60);
	DIR *dir = NULL;
	struct dirent *file = NULL;
	struct plugind *cd;

	// enable the apps plugin by default
	// config_get_boolean("plugins", "apps", 1);

	if(scan_frequency < 1) scan_frequency = 1;

	while(likely(1)) {
		if(unlikely(netdata_exit)) break;

		dir = opendir(dir_name);
		if(unlikely(!dir)) {
			error("Cannot open directory '%s'.", dir_name);
			pthread_exit(NULL);
			return NULL;
		}

		while(likely((file = readdir(dir)))) {
			if(unlikely(netdata_exit)) break;

			debug(D_PLUGINSD, "PLUGINSD: Examining file '%s'", file->d_name);

			if(unlikely(strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)) continue;

			int len = (int) strlen(file->d_name);
			if(unlikely(len <= (int)PLUGINSD_FILE_SUFFIX_LEN)) continue;
			if(unlikely(strcmp(PLUGINSD_FILE_SUFFIX, &file->d_name[len - (int)PLUGINSD_FILE_SUFFIX_LEN]) != 0)) {
				debug(D_PLUGINSD, "PLUGINSD: File '%s' does not end in '%s'.", file->d_name, PLUGINSD_FILE_SUFFIX);
				continue;
			}

			char pluginname[CONFIG_MAX_NAME + 1];
			snprintf(pluginname, CONFIG_MAX_NAME, "%.*s", (int)(len - PLUGINSD_FILE_SUFFIX_LEN), file->d_name);
			int enabled = config_get_boolean("plugins", pluginname, automatic_run);

			if(unlikely(!enabled)) {
				debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is not enabled", file->d_name);
				continue;
			}

			// check if it runs already
			for(cd = pluginsd_root ; likely(cd) ; cd = cd->next) {
				if(unlikely(strcmp(cd->filename, file->d_name) == 0)) break;
			}
			if(likely(cd && !cd->obsolete)) {
				debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is already running", cd->filename);
				continue;
			}

			// it is not running
			// allocate a new one, or use the obsolete one
			if(unlikely(!cd)) {
				cd = calloc(sizeof(struct plugind), 1);
				if(unlikely(!cd)) fatal("Cannot allocate memory for plugin.");

				snprintf(cd->id, CONFIG_MAX_NAME, "plugin:%s", pluginname);

				strncpy(cd->filename, file->d_name, FILENAME_MAX);
				snprintf(cd->fullfilename, FILENAME_MAX, "%s/%s", dir_name, cd->filename);

				cd->enabled = enabled;
				cd->update_every = (int) config_get_number(cd->id, "update every", rrd_update_every);
				cd->started_t = time(NULL);

				char *def = "";
				snprintf(cd->cmd, PLUGINSD_CMD_MAX, "exec %s %d %s", cd->fullfilename, cd->update_every, config_get(cd->id, "command options", def));

				// link it
				if(likely(pluginsd_root)) cd->next = pluginsd_root;
				pluginsd_root = cd;
			}
			cd->obsolete = 0;

			if(unlikely(!cd->enabled)) continue;

			// spawn a new thread for it
			if(unlikely(pthread_create(&cd->thread, NULL, pluginsd_worker_thread, cd) != 0)) {
				error("PLUGINSD: failed to create new thread for plugin '%s'.", cd->filename);
				cd->obsolete = 1;
			}
			else if(unlikely(pthread_detach(cd->thread) != 0))
				error("PLUGINSD: Cannot request detach of newly created thread for plugin '%s'.", cd->filename);
		}

		closedir(dir);
		sleep((unsigned int) scan_frequency);
	}

	pthread_exit(NULL);
	return NULL;
}
/*
 * this function is intended to be invoked as an argument to pthread_create,
 */
static void *_gnix_dgram_prog_thread_fn(void *the_arg)
{
	int ret = FI_SUCCESS, prev_state;
	struct gnix_dgram_hndl *the_hndl = (struct gnix_dgram_hndl *)the_arg;
	sigset_t  sigmask;

	/*
	 * TODO: need to add a lock?
	 */

	GNIX_TRACE(FI_LOG_EP_CTRL, "\n");

	/*
	 * temporarily disable cancelability while we set up
	 * some stuff
	 */

	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &prev_state);

	/*
	 * help out Cray core-spec, say we're not an app thread
	 * and can be run on core-spec cpus.
	 */

	ret = _gnix_task_is_not_app();
	if (ret)
		GNIX_WARN(FI_LOG_EP_CTRL,
		"_gnix_task_is_not_app call returned %d\n", ret);

	/*
	 * block all signals, don't want this thread to catch
	 * signals that may be for app threads
	 */

	memset(&sigmask, 0, sizeof(sigset_t));
	ret = sigfillset(&sigmask);
	if (ret) {
		GNIX_WARN(FI_LOG_EP_CTRL,
		"sigfillset call returned %d\n", ret);
	} else {

		ret = pthread_sigmask(SIG_SETMASK,
					&sigmask, NULL);
		if (ret)
			GNIX_WARN(FI_LOG_EP_CTRL,
			"pthread_sigmask call returned %d\n", ret);
	}

	/*
	 * okay now we're ready to be cancelable.
	 */

	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &prev_state);

	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

retry:
	ret = _gnix_dgram_poll(the_hndl, GNIX_DGRAM_BLOCK);
	if ((ret == -FI_ETIMEDOUT) || (ret == FI_SUCCESS))
		goto retry;

	GNIX_WARN(FI_LOG_EP_CTRL,
		"_gni_dgram_poll returned %d\n", ret);

	/*
	 * TODO: need to be able to enqueue events on to the
	 * ep associated with the cm_nic.
	 */
	return NULL;
}
Example #4
0
int main(int argc, char **argv)
{
	int c, error = 0;
	struct hist_data h;
	int retlog;
	char tmp[MAXBUFSIZ];
	char *fullurl;
	extern char *optarg;
	extern int optind;
	sigset_t set;

	main_tid = pthread_self();
	/* Allocate heap for download request	
	 * struct request stores all the information that might be
	 * of interest
	 */
	req = (struct request *)calloc(1, sizeof(struct request));

	/* This is required because if download is aborted before
	 * this is initialized, problems will occur
	 */
	wthread = NULL;

	/* except from signal handler thread, 
	 * no other thread is receiving signals!
	 * No signals are caught here since we need to save download job only
	 * after wthread structures are initialized.
	 * TODO:: We need to create helper thread as soon as head request is over
	 * since the user might wish to stop downloading as soon as he sees the
	 * content length.
	 */
	sigfillset(&set);
	pthread_sigmask(SIG_BLOCK, &set, NULL);

	/* Safe to exit before download starts.
	 * This is set back to DEFERRED before creating helper thread because
	 * we want this to exit only at certain safe points specified using
	 * pthread_testcancel().
	 * Helper thread is started just before creating worker threads and after
	 * wthread structures are initialized. Only after this point do we need to
	 * save download job if an interrupt comes - not before. Helper thread exists
	 * only to catch SIGINT and to save download job. It doesn't make sense to
	 * start it before wthread structures are initialized!
	 */
	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);


	/* Read the RC file if exist	*/
	readrc();


	/* If set in rc file	*/
	if (preferredthread != -1)
		nthreads = preferredthread;

	while (!error && (c = getopt(argc,argv,"p:l:n:hfv")) != -1) {
		switch(c) {
			case 'p':
				req->port = atoi(optarg);
				break;
			case 'l':
				strncpy(req->lfile, optarg, MAXBUFSIZ -1);
				break;
			case 'n':
				fsuggested = 1;
				if ((nthreads = atoi(optarg)) > MAXTHREADS) {
					Log("Error: Maximum # of threads allowed is %d\n", MAXTHREADS);
					exit(1);
				}
				break;
			case 'h':
				printf("%s\n", PROGVERSION);
				usage();
				exit(0);
				break;
			case 'v':
				printf("%s\nby Murat BALABAN <*****@*****.**>\n", PROGVERSION);
				exit(0);
				break;
			default:
				error = 1;
				usage();
				exit(1);
				break;
		}
	}

	if (error) {
		usage();
		exit(1);
	}

	if (fsuggested == 1 && nthreads == 0) {
		fprintf(stderr, "ERROR: -f and -n should be used together!, exiting...\n");
		usage();
		exit(1);
	}

	if (argc == 2) 		/* If only url is supplied... */
		fullurl = strdup(argv[1]);
	else
	if (optind < argc)
		if (argc > 2)
			fullurl = strdup(argv[optind]);
		else {
			usage();
			exit(1);
		}
	else
	if (optind == argc) {
		usage();
		exit(1);
	}

	parse_url(fullurl, req);


	if(strlen(req->lfile) == 0)
		strncpy(req->lfile, req->file, MAXBUFSIZ - 2);

	getcwd(tmp, MAXBUFSIZ -2);
	strncpy(tmp+strlen(tmp), "/", MAXBUFSIZ - strlen(tmp) - 2);
	strncpy(tmp+strlen(tmp), req->lfile, MAXBUFSIZ - strlen(tmp) - 3);
	strncpy(req->lfile, tmp, MAXBUFSIZ - 2);

	/* If a log file for a previous try has been found, read it and
	 * resume the download job (resume_get), otherwise, start with
	 * a clean job (get)
	 *
	 * Logfile is of the pattern: aget-$file_name.log
	 */
	switch(req->proto) {
		case PROTO_HTTP:
			if ((retlog = read_log(&h)) != -1)
				resumeDownload(&h, PROTO_HTTP);
			else
				startHTTP(req);
			break;
		case PROTO_FTP:
			if ((retlog = read_log(&h)) != -1)
				resumeDownload(&h, PROTO_FTP);
			else
				startFTP(req);
			break;
	}
	return 0;
}
Example #5
0
void SpaceBall::deviceThread(void)
{
    /* Set thread's cancellation state: */
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
    
    /* Receive lines from the serial port until interrupted: */
    while(true)
    {
        /* Read characters until an end-of-line is encountered: */
        unsigned char packet[256];
        int packetLength=readPacket(256,packet);
        
        /* Determine the packet type: */
        switch(packet[0])
        {
            case 'D':
            {
                /* Parse a data packet: */
                short int rawData[6];
                rawData[0]=(short int)(((unsigned int)packet[ 3]<<8)|(unsigned int)packet[ 4]);
                rawData[1]=(short int)(((unsigned int)packet[ 5]<<8)|(unsigned int)packet[ 6]);
                rawData[2]=(short int)(((unsigned int)packet[ 7]<<8)|(unsigned int)packet[ 8]);
                rawData[3]=(short int)(((unsigned int)packet[ 9]<<8)|(unsigned int)packet[10]);
                rawData[4]=(short int)(((unsigned int)packet[11]<<8)|(unsigned int)packet[12]);
                rawData[5]=(short int)(((unsigned int)packet[13]<<8)|(unsigned int)packet[14]);
                
                /* Convert axis states to floats: */
                float newAxisStates[6];
                for(int i=0;i<6;++i)
                {
                    bool neg=rawData[i]<0;
                    if(i%3==2)
                        neg=!neg;
                    newAxisStates[i]=float(abs(rawData[i]));
                    if(newAxisStates[i]>thresholds[i])
                        newAxisStates[i]-=thresholds[i];
                    else
                        newAxisStates[i]=0.0f;
                    newAxisStates[i]*=gains[i];
                    newAxisStates[i]=float(pow(newAxisStates[i],exponents[i]));
                    if(neg)
                        newAxisStates[i]=-newAxisStates[i];
                }
                
                /* Call event handler: */
                processAxisEvent(newAxisStates,axisStates);
                
                /* Update state arrays: */
                for(int i=0;i<6;++i)
                    axisStates[i]=newAxisStates[i];
                break;
            }
            
            case '.':
            {
                /* Parse a button event packet: */
                int buttonMask=0x0;
                buttonMask|=int(packet[2]&0x3f);
                buttonMask|=int(packet[2]&0x80)>>1;
                buttonMask|=int(packet[1]&0x1f)<<7;
                
                /* Convert button state mask to booleans: */
                bool newButtonStates[13];
                for(int i=0;i<13;++i)
                    newButtonStates[i]=buttonMask&(1<<i);
                
                /* Call event handler: */
                processButtonEvent(newButtonStates,buttonStates);
                
                /* Update state arrays: */
                for(int i=0;i<13;++i)
                    buttonStates[i]=newButtonStates[i];
                break;
            }
        }
    }
}
Example #6
0
static void *_decay_thread(void *no_data)
{
	struct job_record *job_ptr = NULL;
	ListIterator itr;
	time_t start_time = time(NULL);
	time_t last_ran = 0;
	time_t last_reset = 0, next_reset = 0;
	uint32_t calc_period = slurm_get_priority_calc_period();
	double decay_hl = (double)slurm_get_priority_decay_hl();
	double decay_factor = 1;
	uint16_t reset_period = slurm_get_priority_reset_period();

	/* Write lock on jobs, read lock on nodes and partitions */
	slurmctld_lock_t job_write_lock =
		{ NO_LOCK, WRITE_LOCK, READ_LOCK, READ_LOCK };
	assoc_mgr_lock_t locks = { WRITE_LOCK, NO_LOCK,
				   NO_LOCK, NO_LOCK, NO_LOCK };

	if (decay_hl > 0)
		decay_factor = 1 - (0.693 / decay_hl);

	(void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	(void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	_read_last_decay_ran(&last_ran, &last_reset);
	if (last_reset == 0)
		last_reset = start_time;

	_init_grp_used_cpu_run_secs(last_ran);

	while (1) {
		time_t now = start_time;
		double run_delta = 0.0, real_decay = 0.0;

		slurm_mutex_lock(&decay_lock);
		running_decay = 1;

		/* If reconfig is called handle all that happens
		   outside of the loop here */
		if (reconfig) {
			/* if decay_hl is 0 or less that means no
			   decay is to be had.  This also means we
			   flush the used time at a certain time
			   set by PriorityUsageResetPeriod in the slurm.conf
			*/
			calc_period = slurm_get_priority_calc_period();
			reset_period = slurm_get_priority_reset_period();
			next_reset = 0;
			decay_hl = (double)slurm_get_priority_decay_hl();
			if (decay_hl > 0)
				decay_factor = 1 - (0.693 / decay_hl);
			else
				decay_factor = 1;

			reconfig = 0;
		}

		/* this needs to be done right away so as to
		 * incorporate it into the decay loop.
		 */
		switch(reset_period) {
		case PRIORITY_RESET_NONE:
			break;
		case PRIORITY_RESET_NOW:	/* do once */
			_reset_usage();
			reset_period = PRIORITY_RESET_NONE;
			last_reset = now;
			break;
		case PRIORITY_RESET_DAILY:
		case PRIORITY_RESET_WEEKLY:
		case PRIORITY_RESET_MONTHLY:
		case PRIORITY_RESET_QUARTERLY:
		case PRIORITY_RESET_YEARLY:
			if (next_reset == 0) {
				next_reset = _next_reset(reset_period,
							 last_reset);
			}
			if (now >= next_reset) {
				_reset_usage();
				last_reset = next_reset;
				next_reset = _next_reset(reset_period,
							 last_reset);
			}
		}

		/* now calculate all the normalized usage here */
		assoc_mgr_lock(&locks);
		_set_children_usage_efctv(
			assoc_mgr_root_assoc->usage->childern_list);
		assoc_mgr_unlock(&locks);

		if (!last_ran)
			goto get_usage;
		else
			run_delta = difftime(start_time, last_ran);

		if (run_delta <= 0)
			goto get_usage;

		real_decay = pow(decay_factor, run_delta);

		if (priority_debug)
			info("Decay factor over %g seconds goes "
			     "from %.15f -> %.15f",
			     run_delta, decay_factor, real_decay);

		/* first apply decay to used time */
		if (_apply_decay(real_decay) != SLURM_SUCCESS) {
			error("problem applying decay");
			running_decay = 0;
			slurm_mutex_unlock(&decay_lock);
			break;
		}
		lock_slurmctld(job_write_lock);
		itr = list_iterator_create(job_list);
		while ((job_ptr = list_next(itr))) {
			/* apply new usage */
			if (!IS_JOB_PENDING(job_ptr) &&
			    job_ptr->start_time && job_ptr->assoc_ptr) {
				if (!_apply_new_usage(job_ptr, decay_factor,
						      last_ran, start_time))
					continue;
			}

			/*
			 * Priority 0 is reserved for held jobs. Also skip
			 * priority calculation for non-pending jobs.
			 */
			if ((job_ptr->priority == 0)
			    || !IS_JOB_PENDING(job_ptr))
				continue;

			job_ptr->priority =
				_get_priority_internal(start_time, job_ptr);
			last_job_update = time(NULL);
			debug2("priority for job %u is now %u",
			       job_ptr->job_id, job_ptr->priority);
		}
		list_iterator_destroy(itr);
		unlock_slurmctld(job_write_lock);

	get_usage:
		last_ran = start_time;

		_write_last_decay_ran(last_ran, last_reset);

		running_decay = 0;
		slurm_mutex_unlock(&decay_lock);

		/* Sleep until the next time. */
		now = time(NULL);
		double elapsed = difftime(now, start_time);
		if (elapsed < calc_period) {
			sleep(calc_period - elapsed);
			start_time = time(NULL);
		} else
			start_time = now;
		/* repeat ;) */
	}
	return NULL;
}
Example #7
0
File: hbserv.c Project: CsBela/core
static void * s_signalListener( void * my_stack )
{
   static HB_BOOL bFirst = HB_TRUE;
   sigset_t       passall;
   HB_STACK *     pStack = ( HB_STACK * ) my_stack;

#if defined( HB_OS_BSD )
   int sig;
#else
   siginfo_t sinfo;
#endif

#ifdef HB_THREAD_TLS_KEYWORD
   hb_thread_stack = my_stack;
#else
   pthread_setspecific( hb_pkCurrentStack, my_stack );
#endif

   pStack->th_id = HB_CURRENT_THREAD();
   hb_threadLinkStack( pStack );
   HB_STACK_LOCK;

   /* and now accepts all signals */
   sigemptyset( &passall );

   /* and wait for all signals */
   sigaddset( &passall, SIGHUP );
   sigaddset( &passall, SIGQUIT );
   sigaddset( &passall, SIGILL );
   sigaddset( &passall, SIGABRT );
   sigaddset( &passall, SIGFPE );
   sigaddset( &passall, SIGSEGV );
   sigaddset( &passall, SIGTERM );
   sigaddset( &passall, SIGUSR1 );
   sigaddset( &passall, SIGUSR2 );
   sigaddset( &passall, SIGHUP );

   pthread_cleanup_push( hb_threadTerminator, my_stack );
   pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, NULL );
   pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );

   for(;; )
   {
      /* allow safe cancelation */
      HB_STACK_UNLOCK;

      /* reset signal handling; this is done here (so I don't
         mangle with pthread_ calls, and I don't hold mutexes),
         and just once (doing it twice would be useless). */
      if( bFirst )
      {
         pthread_sigmask( SIG_SETMASK, &passall, NULL );
         bFirst = HB_FALSE;
      }

      /* This is also a cancelation point. When the main thread
         is done, it will kill all the threads having a stack
         including this one.
         ATM we don't care very much about signal handling during
         termination: no handler is set for them, so the DFL
         action is taken (and that should be fine). */
#if defined( HB_OS_BSD )
      sigwait( &passall, &sig );
#else
      sigwaitinfo( &passall, &sinfo );
#endif

      /* lock stack before passing the ball to VM. */
      HB_STACK_LOCK;
#if defined( HB_OS_BSD )
      s_signalHandler( sig, NULL, NULL );
#else
      s_signalHandler( sinfo.si_signo, &sinfo, NULL );
#endif
   }

   pthread_cleanup_pop( 1 );
   return 0;
}
Example #8
0
/* Critical Section: We are accessing files that may be written to by multiple
 * threads. These must be opened in the critical section to ensure the threads
 * are seeked to the correct point.
 * */
void *pidMonitorHelper(void *ptr) {
   time_t t;
   pid_t pid; 
   char *ct, procStat[25], procStatm[25];
   int y, whichMutexToUse = 0;
   FILE *pidstatm, *pidstat;
   monitor_data *sys = (monitor_data *) ptr;

   pid = (pid_t)strtoimax(sys->pidBeingMonitored, NULL, 10);
   /* Match up the logfile with the mutexxx */
   for(y = 0; y < 10; y++) {
      if(strcmp(sys->logfile, pairs[y].logfile) == 0) {
         whichMutexToUse = pairs[y].mutexIndex;
         break;
      }
   }
   sprintf(procStat, "/proc/%d/stat", pid);
   sprintf(procStatm, "/proc/%d/statm", pid);

   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
   while(1) {
      /* attain the lock */
      pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
      /* We use a mutex because only one thread may write to a file at a time */
      pthread_mutex_lock(&m[whichMutexToUse]);

      /* Open everything */
      /* Whenever writing to a shared file, you must make sure only 1 thread
       * is writing to it at a time else you're output will be messy
       * */
      sys->logFP = fopen(sys->logfile, "a");
      pidstatm = fopen(procStatm, "r");
      pidstat = fopen(procStat, "r");
      if(pidstat == NULL || pidstatm == NULL) {
         fclose(sys->logFP);
         break;
      }

      /* Begin statistic tracking */
      time(&t);
      ct = ctime(&t);
      ct[strlen(ct) - 1] = ']';
      fprintf(sys->logFP, "[%s ", ct);
      fprintf(sys->logFP, "Process  ");
      getPidStatData(&sys->logFP, &pidstat);
      getPidStatmData(&sys->logFP, &pidstatm);//wtf how do pass FILE pointers in C?

      /* Close everything  */
      fclose(pidstatm);
      fclose(pidstat);
      fprintf(sys->logFP, "\n");
      fclose(sys->logFP);

      /* Performance Concerns: Opening and closing files over and over again
       * makes the program slower, but it is necessary to ensure data is not
       * overwritten or race conditions do not occur. 
       * */
      pthread_mutex_unlock(&m[whichMutexToUse]);
      pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
      usleep(sys->monitorInterval);
   }
   return 0;
}
Example #9
0
// Function that serves as the starting address for a Linux thread
void * OsTaskLinux::taskEntry(void* arg)
{
   OsStatus                  res;
   int                       linuxRes;
   OsTaskLinux*              pTask;
   pthread_attr_t            attributes;
   struct sched_param        param;

   pTask = (OsTaskLinux*) arg;

   // If we ever receive a thread cancel request, it means that the OsTask
   // object is in the process of being destroyed.  To avoid the situation
   // where a thread attempts to run after its containing OsTask object has
   // been freed, we set the thread up so that the cancel takes effect
   // immediately (as opposed to waiting until the next thread cancellation
   // point).
   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

   if (linuxTaskStartSuspended)
   {
      pthread_kill(pthread_self(), SIGSTOP);
   }

  // construct thread attribute
   linuxRes = pthread_attr_init(&attributes);
   if (linuxRes != 0) {
      OsSysLog::add(FAC_KERNEL, PRI_ERR, "OsTaskLinux::taskEntry: pthread_attr_init failed (%d) ", linuxRes);
   }

   int linuxPriority = OsUtilLinux::cvtOsPrioToLinuxPrio(pTask->mPriority);

   if((geteuid() == 0) && (linuxPriority != RT_NO))
   {
      // Use FIFO realtime scheduling
      param.sched_priority = linuxPriority;

#if defined(__APPLE__)
      linuxRes = ~POSIX_OK;
#else
      linuxRes = sched_setscheduler(0, SCHED_FIFO, &param); 
#endif

      if (linuxRes == POSIX_OK)
      {
         OsSysLog::add(FAC_KERNEL, PRI_INFO, 
                       "OsTaskLinux::taskEntry: starting %s at RT linux priority: %d", 
                       pTask->mName.data(), linuxPriority);
      }
      else
      {
         OsSysLog::add(FAC_KERNEL, PRI_ERR, 
                       "OsTaskLinux::taskEntry: failed to set RT linux priority: %d for task: %s", 
                       linuxPriority, pTask->mName.data());
      }

      // keep all memory locked into physical mem, to guarantee realtime-behaviour
      if (linuxRes == POSIX_OK)
      {
         linuxRes = mlockall(MCL_CURRENT|MCL_FUTURE);
         if (linuxRes != POSIX_OK)
         {
            OsSysLog::add(FAC_KERNEL, PRI_ERR, 
                          "OsTaskLinux::taskEntry: failed to lock memory for task: %s", 
                          pTask->mName.data());
         }
      }
   }

   // Run the code the task is supposed to run, namely the run()
   // method of its class.

   // Mark the task as not safe to delete.
   res = pTask->mDeleteGuard.acquireRead();
   assert(res == OS_SUCCESS);

   unsigned int returnCode = pTask->run(pTask->getArg());

   // After run returns be sure to mark the thread as shut down.
   pTask->ackShutdown();

   // Then remove it from the OsNameDb.
   pTask->taskUnregister();

   // Mark the task as now safe to delete.
   res = pTask->mDeleteGuard.releaseRead();
   assert(res == OS_SUCCESS);

   return ((void *)returnCode);
}
Example #10
0
static void* ThreadSend(void* data)
{
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
    
    ClientNet* pNet = (ClientNet*)data;
    
    fd_set fdwrite;
    timeval block_time;
    block_time.tv_sec = 0;
    block_time.tv_usec = GT_NET_BLOCK_TIME;
    
    LPBYTE pMsg = NULL, pTempPtr = NULL;
    DWORD dwMsgSize = 0;
    int nReturn = 0;
    
    while (!pNet->IsTerminateSend())
    {
        for(;;)
        {
            pTempPtr = pMsg = pNet->GetSendMsg(dwMsgSize);
        
            if(NULL == pMsg)
                break;
            
            while( dwMsgSize > 0 && !pNet->IsTerminateSend())
            {
                nReturn = send(pNet->GetSocket(), (char*)pTempPtr, dwMsgSize, 0);
                if(SOCKET_ERROR == nReturn)
                {
                    switch (errno)
                    {
                    case EWOULDBLOCK:
                    case ENOBUFS:
                        {
                            FD_ZERO(&fdwrite);
                            FD_SET(pNet->GetSocket(), &fdwrite);
                            select(pNet->GetSocket() + 1, NULL, &fdwrite, NULL, &block_time);
                        }
                        break;
                            
                    default:
                            shutdown(pNet->GetSocket(), 1);
                            free(pMsg);
                            goto __thread_send_end;
                            break;
                    }
                    free(pMsg);
                    shutdown(pNet->GetSocket(), 1);
                    goto __thread_send_end;
                }
                else
                {
                    pTempPtr += nReturn;
                    dwMsgSize -= nReturn;
                }
            }
            
            free(pMsg);
            pTempPtr = pMsg = NULL;
        }
        
    }
__thread_send_end:
    pNet->SetConnected(false);
    pthread_exit(NULL);
    return NULL;
}
Example #11
0
/*
 * function handle_requests_loop(): infinite loop of requests handling
 * algorithm: forever, if there are requests to handle, take the first
 *            and handle it. Then wait on the given condition variable,
 *            and when it is signaled, re-do the loop.
 *            increases number of pending requests by one.
 * input:     id of thread, for printing purposes.
 * output:    none.
 */
void*
handle_requests_loop(void* thread_params)
{
    int rc;	                    /* return code of pthreads functions.  */
    struct request* a_request;      /* pointer to a request.               */
    struct handler_thread_params *data;
 				    /* hadler thread's parameters */

    /* sanity check -make sure data isn't NULL */
    data = (struct handler_thread_params*)thread_params;
    assert(data);

    printf("Starting thread '%d'\n", data->thread_id);
    fflush(stdout);

    /* set my cancel state to 'enabled', and cancel type to 'defered'. */
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

    /* set thread cleanup handler */
    pthread_cleanup_push(cleanup_free_mutex, (void*)data->request_mutex);

    /* lock the mutex, to access the requests list exclusively. */
    rc = pthread_mutex_lock(data->request_mutex);

#ifdef DEBUG
    printf("thread '%d' after pthread_mutex_lock\n", data->thread_id);
    fflush(stdout);
#endif /* DEBUG */

    /* do forever.... */
    while (1) {
        int num_requests = get_requests_number(data->requests);

#ifdef DEBUG
    	printf("thread '%d', num_requests =  %d\n",
	       data->thread_id, num_requests);
    	fflush(stdout);
#endif /* DEBUG */
	if (num_requests > 0) { /* a request is pending */
	    a_request = get_request(data->requests);
	    if (a_request) { /* got a request - handle it and free it */
		handle_request(a_request, data->thread_id);
		free(a_request);
	    }
	}
	else {
	    /* the thread checks the flag before waiting            */
	    /* on the condition variable.                           */
	    /* if no new requests are going to be generated, exit.  */
	    if (done_creating_requests) {
                pthread_mutex_unlock(data->request_mutex);
		printf("thread '%d' exiting\n", data->thread_id);
		fflush(stdout);
		pthread_exit(NULL);
	    }
	    /* wait for a request to arrive. note the mutex will be */
	    /* unlocked here, thus allowing other threads access to */
	    /* requests list.                                       */
#ifdef DEBUG
    	    printf("thread '%d' before pthread_cond_wait\n", data->thread_id);
    	    fflush(stdout);
#endif /* DEBUG */
	    rc = pthread_cond_wait(data->got_request, data->request_mutex);
	    /* and after we return from pthread_cond_wait, the mutex  */
	    /* is locked again, so we don't need to lock it ourselves */
#ifdef DEBUG
    	    printf("thread '%d' after pthread_cond_wait\n", data->thread_id);
    	    fflush(stdout);
#endif /* DEBUG */
	}
    }

    /* remove thread cleanup handler. never reached, but we must use */
    /* it here, according to pthread_cleanup_push's manual page.     */
    pthread_cleanup_pop(0);
}
Example #12
0
/**
 * This is the streaming server, run as a separate thread
 * This function waits for a client to connect, and send the grayscaled images
 */
void* streamServer(void* arg) {
	struct sockaddr_in server;

	/* make this thread cancellable using pthread_cancel() */
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL );
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL );

	/* open socket */
	if ((serversock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
		quit("socket() failed", 1);
	}

	/* setup server's IP and port */
	memset(&server, 0, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = INADDR_ANY;

	/* bind the socket */
	if (bind(serversock, (const void*) &server, sizeof(server)) == -1) {
		quit("bind() failed", 1);
	}

	/* wait for connection */
	if (listen(serversock, 10) == -1) {
		quit("listen() failed.", 1);
	}

	/* accept a client */
	if ((clientsock = accept(serversock, NULL, NULL )) == -1) {
		quit("accept() failed", 1);
	}

	/* the size of the data to be sent */
	int imgsize = img1->imageSize;
	int bytes, i;

	/* start sending images */
	while (1) {
		/* send the grayscaled frame, thread safe */
		pthread_mutex_lock(&mutex);
		if (is_data_ready) {
			bytes = send(clientsock, img1->imageData, imgsize, 0);
			is_data_ready = 0;
		}
		pthread_mutex_unlock(&mutex);

		/* if something went wrong, restart the connection */
		if (bytes != imgsize) {
			fprintf(stderr, "Connection closed.\n");
			close(clientsock);

			if ((clientsock = accept(serversock, NULL, NULL )) == -1) {
				quit("accept() failed", 1);
			}
		}

		/* have we terminated yet? */
		pthread_testcancel();

		/* no, take a rest for a while */
		usleep(1000);
	}
}
Example #13
0
static int
jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params, JSList * slave_names, JSList * load_list)
{
	int sig;
	int i;
	sigset_t allsignals;
	struct sigaction action;
	int waiting;
	JSList * node;

	/* ensure that we are in our own process group so that
	   kill (SIG, -pgrp) does the right thing.
	*/

	setsid ();

	pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	/* what's this for?

	   POSIX says that signals are delivered like this:

	   * if a thread has blocked that signal, it is not
	       a candidate to receive the signal.
           * of all threads not blocking the signal, pick
	       one at random, and deliver the signal.

           this means that a simple-minded multi-threaded program can
           expect to get POSIX signals delivered randomly to any one
           of its threads,

	   here, we block all signals that we think we might receive
	   and want to catch. all "child" threads will inherit this
	   setting. if we create a thread that calls sigwait() on the
	   same set of signals, implicitly unblocking all those
	   signals. any of those signals that are delivered to the
	   process will be delivered to that thread, and that thread
	   alone. this makes cleanup for a signal-driven exit much
	   easier, since we know which thread is doing it and more
	   importantly, we are free to call async-unsafe functions,
	   because the code is executing in normal thread context
	   after a return from sigwait().
	*/

	sigemptyset (&signals);
	sigaddset(&signals, SIGHUP);
	sigaddset(&signals, SIGINT);
	sigaddset(&signals, SIGQUIT);
	sigaddset(&signals, SIGPIPE);
	sigaddset(&signals, SIGTERM);
	sigaddset(&signals, SIGUSR1);
	sigaddset(&signals, SIGUSR2);

	/* all child threads will inherit this mask unless they
	 * explicitly reset it 
	 */

	pthread_sigmask (SIG_BLOCK, &signals, 0);

	if (!realtime && client_timeout == 0)
		client_timeout = 500; /* 0.5 sec; usable when non realtime. */

	/* get the engine/driver started */

	if ((engine = jack_engine_new (realtime, realtime_priority, 
				       do_mlock, do_unlock, server_name,
				       temporary, verbose, client_timeout,
				       port_max, getpid(), frame_time_offset, 
				       nozombies, timeout_count_threshold, drivers)) == 0) {
		jack_error ("cannot create engine");
		return -1;
	}

	jack_info ("loading driver ..");
	
	if (jack_engine_load_driver (engine, driver_desc, driver_params)) {
		jack_error ("cannot load driver module %s",
			 driver_desc->name);
		goto error;
	}

	for (node=slave_names; node; node=jack_slist_next(node)) {
		char *sl_name = node->data;
		jack_driver_desc_t *sl_desc = jack_find_driver_descriptor(sl_name);
		if (sl_desc) {
			jack_engine_load_slave_driver(engine, sl_desc, NULL);
		}
	}


	if (jack_drivers_start (engine) != 0) {
		jack_error ("cannot start driver");
		goto error;
	}

        jack_load_internal_clients (load_list);

	/* install a do-nothing handler because otherwise pthreads
	   behaviour is undefined when we enter sigwait.
	*/

	sigfillset (&allsignals);
	action.sa_handler = do_nothing_handler;
	action.sa_mask = allsignals;
	action.sa_flags = SA_RESTART|SA_RESETHAND;

	for (i = 1; i < NSIG; i++) {
		if (sigismember (&signals, i)) {
			sigaction (i, &action, 0);
		} 
	}
	
	if (verbose) {
		jack_info ("%d waiting for signals", getpid());
	}

	waiting = TRUE;

	while (waiting) {
		sigwait (&signals, &sig);

		jack_info ("jack main caught signal %d", sig);
		
		switch (sig) {
		case SIGUSR1:
			jack_dump_configuration(engine, 1);
			break;
		case SIGUSR2:
			/* driver exit */
			waiting = FALSE;
			break;
		default:
			waiting = FALSE;
			break;
		}
	} 
	
	if (sig != SIGSEGV) {

		/* unblock signals so we can see them during shutdown.
		   this will help prod developers not to lose sight of
		   bugs that cause segfaults etc. during shutdown.
		*/
		sigprocmask (SIG_UNBLOCK, &signals, 0);
	}
	
	jack_engine_delete (engine);
	return 1;
	
error:
	jack_engine_delete (engine);
	return -1;
}
Example #14
0
/*main thread routine for this bus*/
void *thr_sendrec_DCCAR(void *v)
{
    int addr, ctr;
    struct timeval akt_time, cmp_time;
    ga_state_t gatmp;
    int last_cancel_state, last_cancel_type;

    bus_thread_t *btd = (bus_thread_t *) malloc(sizeof(bus_thread_t));

    if (btd == NULL)
        pthread_exit((void *) 1);
    btd->bus = (bus_t) v;
    btd->fd = -1;

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &last_cancel_state);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &last_cancel_type);

    /*register cleanup routine */
    pthread_cleanup_push((void *) end_bus_thread, (void *) btd);

    syslog_bus(btd->bus, DBG_INFO, "DC-Car bus started (device = %s).",
               buses[btd->bus].device.file.path);

    /*enter endless loop to process work tasks */
    while (true) {
        buses[btd->bus].watchdog = 1;

        /*POWER action arrived */
        if (buses[btd->bus].power_changed == 1)
            handle_power_command(btd->bus);

        /* loop shortcut to prevent processing of GA, GL (and FB)
         * without power on; arriving commands will flood the command
         * queue */
        if (buses[btd->bus].power_state == 0) {

            /* wait 1 ms */
            if (usleep(1000) == -1) {
                syslog_bus(btd->bus, DBG_ERROR,
                           "usleep() failed: %s (errno = %d)\n",
                           strerror(errno), errno);
            }
            continue;
        }

        /*GL action arrived */
        if (!queue_GL_isempty(btd->bus))
            handle_gl_command(btd->bus);

        /*FB action arrived */
        /* currently nothing to do here */
        buses[btd->bus].watchdog++;

        /* busy wait and continue loop */
        /* wait 1 ms */
        if (usleep(1000) == -1) {
            syslog_bus(btd->bus, DBG_ERROR,
                       "usleep() failed: %s (errno = %d)\n",
                       strerror(errno), errno);
        }
    }

    /*run the cleanup routine */
    pthread_cleanup_pop(1);
    return NULL;
}
void *stapi_read_thread(void *sparam) {
	int32_t dev_index, ErrorCode, i, j, CRCValid;
	uint32_t QueryBufferHandle = 0, DataSize = 0;
	uchar buf[BUFFLEN];

	struct read_thread_param *para = sparam;
	dev_index = para->id;

	pthread_setspecific(getclient, para->cli);
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
	pthread_cleanup_push(stapi_cleanup_thread, (void*) dev_index);

	int32_t error_count = 0;

	while (1) {
		QueryBufferHandle = 0;
		ErrorCode = oscam_stapi_SignalWaitBuffer(dev_list[dev_index].SignalHandle, &QueryBufferHandle, 1000);

		switch (ErrorCode) {
			case 0: // NO_ERROR:
				break;
			case 852042: // ERROR_SIGNAL_ABORTED
				cs_log("Caught abort signal");
				pthread_exit(NULL);
				break;
			case 11: // ERROR_TIMEOUT:
				//cs_log("timeout %d", dev_index);
				//TODO: if pidindex == -1 try next
				continue;
				break;
			default:
				if (QueryBufferHandle != 0) {
					cs_log("SignalWaitBuffer error: %d", ErrorCode);
					oscam_stapi_BufferFlush(QueryBufferHandle);
					continue;
				}
				cs_log("SignalWaitBuffer: index %d ErrorCode: %d - QueryBuffer: %x", dev_index, ErrorCode, QueryBufferHandle);
				error_count++;
				if (error_count>10) {
					cs_log("Too many errors in reader thread %d, quitting.", dev_index);
					pthread_exit(NULL);
				}
				continue;
				break;
		}

		uint32_t NumFilterMatches = 0;
		int32_t demux_id = 0, filter_num = 0;
		DataSize = 0;
		uint32_t k;

		uint32_t MatchedFilterList[10];
		ErrorCode = oscam_stapi_BufferReadSection(QueryBufferHandle, MatchedFilterList, 10, &NumFilterMatches, &CRCValid, buf, BUFFLEN, &DataSize);

		if (ErrorCode != 0) {
			cs_log("BufferRead: index: %d ErrorCode: %d", dev_index, ErrorCode);
			cs_sleepms(1000);
			continue;
		}

		if (DataSize<=0)
			continue;

		pthread_mutex_lock(&filter_lock); // don't use cs_lock() here; multiple threads using same s_client struct
		for(k=0;k<NumFilterMatches;k++) {
			for (i=0;i<MAX_DEMUX;i++) {
				for (j=0;j<MAX_FILTER;j++) {
					if (dev_list[dev_index].demux_fd[i][j].fd == MatchedFilterList[k]) {
						demux_id=i;
						filter_num=j;

						dvbapi_process_input(demux_id, filter_num, buf, DataSize);
					}
				}
			}
		}
		pthread_mutex_unlock(&filter_lock);
	}
	pthread_cleanup_pop(0);
}
Example #16
0
void *socket_listen_main(void *ptr)
{
	if(ptr) { ; }

	info("WEB SERVER thread created with task id %d", gettid());

	struct web_client *w;
	struct timeval tv;
	int retval;

	if(ptr) { ; }

	if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
		error("Cannot set pthread cancel type to DEFERRED.");

	if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
		error("Cannot set pthread cancel state to ENABLE.");

	web_client_timeout = (int) config_get_number("global", "disconnect idle web clients after seconds", DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS);
	web_enable_gzip = config_get_boolean("global", "enable web responses gzip compression", web_enable_gzip);

	if(listen_fd < 0) fatal("LISTENER: Listen socket is not ready.");

	fd_set ifds, ofds, efds;
	int fdmax = listen_fd;

	FD_ZERO (&ifds);
	FD_ZERO (&ofds);
	FD_ZERO (&efds);

	for(;;) {
		tv.tv_sec = 0;
		tv.tv_usec = 200000;

		if(listen_fd >= 0) {
			FD_SET(listen_fd, &ifds);
			FD_SET(listen_fd, &efds);
		}

		// debug(D_WEB_CLIENT, "LISTENER: Waiting...");
		retval = select(fdmax+1, &ifds, &ofds, &efds, &tv);

		if(retval == -1) {
			error("LISTENER: select() failed.");
			continue;
		}
		else if(retval) {
			// check for new incoming connections
			if(FD_ISSET(listen_fd, &ifds)) {
				w = web_client_create(listen_fd);
				if(unlikely(!w)) {
					// no need for error log - web_client_create already logged the error
					continue;
				}

				if(pthread_create(&w->thread, NULL, web_client_main, w) != 0) {
					error("%llu: failed to create new thread for web client.");
					w->obsolete = 1;
				}
				else if(pthread_detach(w->thread) != 0) {
					error("%llu: Cannot request detach of newly created web client thread.", w->id);
					w->obsolete = 1;
				}
			}
			else debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");

		}
		//else {
		//	debug(D_WEB_CLIENT, "LISTENER: select() timeout.");
		//}

		// cleanup unused clients
		for(w = web_clients; w ; w = w?w->next:NULL) {
			if(w->obsolete) {
				debug(D_WEB_CLIENT, "%llu: Removing client.", w->id);
				// pthread_join(w->thread,  NULL);
				w = web_client_free(w);
				log_allocations();
			}
		}
	}

	error("LISTENER: exit!");

	if(listen_fd >= 0) close(listen_fd);
	exit(2);

	return NULL;
}
static void *_decay_thread(void *no_data)
{
	struct job_record *job_ptr = NULL;
	ListIterator itr;
	time_t start_time = time(NULL);
	time_t next_time;
/* 	int sigarray[] = {SIGUSR1, 0}; */
	struct tm tm;
	time_t last_ran = 0;
	time_t last_reset = 0, next_reset = 0;
	uint32_t calc_period = slurm_get_priority_calc_period();
	double decay_hl = (double)slurm_get_priority_decay_hl();
	double decay_factor = 1;
	uint16_t reset_period = slurm_get_priority_reset_period();

	/* Write lock on jobs, read lock on nodes and partitions */
	slurmctld_lock_t job_write_lock =
		{ NO_LOCK, WRITE_LOCK, READ_LOCK, READ_LOCK };
	assoc_mgr_lock_t locks = { WRITE_LOCK, NO_LOCK,
				   NO_LOCK, NO_LOCK, NO_LOCK };

	if (decay_hl > 0)
		decay_factor = 1 - (0.693 / decay_hl);

	(void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	(void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	if (!localtime_r(&start_time, &tm)) {
		fatal("_decay_thread: "
		      "Couldn't get localtime for rollup handler %ld",
		      (long)start_time);
		return NULL;
	}

	_read_last_decay_ran(&last_ran, &last_reset);
	if (last_reset == 0)
		last_reset = start_time;

	_init_grp_used_cpu_run_secs(last_ran);

	while (1) {
		time_t now = time(NULL);
		int run_delta = 0;
		double real_decay = 0.0;

		slurm_mutex_lock(&decay_lock);
		running_decay = 1;

		/* If reconfig is called handle all that happens
		   outside of the loop here */
		if (reconfig) {
			/* if decay_hl is 0 or less that means no
			   decay is to be had.  This also means we
			   flush the used time at a certain time
			   set by PriorityUsageResetPeriod in the slurm.conf
			*/
			calc_period = slurm_get_priority_calc_period();
			reset_period = slurm_get_priority_reset_period();
			next_reset = 0;
			decay_hl = (double)slurm_get_priority_decay_hl();
			if (decay_hl > 0)
				decay_factor = 1 - (0.693 / decay_hl);
			else
				decay_factor = 1;

			reconfig = 0;
		}

		/* this needs to be done right away so as to
		 * incorporate it into the decay loop.
		 */
		switch(reset_period) {
		case PRIORITY_RESET_NONE:
			break;
		case PRIORITY_RESET_NOW:	/* do once */
			_reset_usage();
			reset_period = PRIORITY_RESET_NONE;
			last_reset = now;
			break;
		case PRIORITY_RESET_DAILY:
		case PRIORITY_RESET_WEEKLY:
		case PRIORITY_RESET_MONTHLY:
		case PRIORITY_RESET_QUARTERLY:
		case PRIORITY_RESET_YEARLY:
			if (next_reset == 0) {
				next_reset = _next_reset(reset_period,
							 last_reset);
			}
			if (now >= next_reset) {
				_reset_usage();
				last_reset = next_reset;
				next_reset = _next_reset(reset_period,
							 last_reset);
			}
		}

		if (!last_ran)
			goto get_usage;
		else
			run_delta = (start_time - last_ran);

		if (run_delta <= 0)
			goto get_usage;

		real_decay = pow(decay_factor, (double)run_delta);

		if (priority_debug)
			info("Decay factor over %d seconds goes "
			     "from %.15f -> %.15f",
			     run_delta, decay_factor, real_decay);

		/* first apply decay to used time */
		if (_apply_decay(real_decay) != SLURM_SUCCESS) {
			error("problem applying decay");
			running_decay = 0;
			slurm_mutex_unlock(&decay_lock);
			break;
		}
		lock_slurmctld(job_write_lock);
		itr = list_iterator_create(job_list);
		while ((job_ptr = list_next(itr))) {
			/* apply new usage */
			if (!IS_JOB_PENDING(job_ptr) &&
			    job_ptr->start_time && job_ptr->assoc_ptr) {
				if (!_apply_new_usage(job_ptr, decay_factor,
						      last_ran, start_time))
					continue;
			}

			/*
			 * This means the job is held, 0, or a system
			 * hold, 1. Continue also if the job is not
			 * pending.  There is no reason to set the
			 * priority if the job isn't pending.
			 */
			if ((job_ptr->priority <= 1)
			    || !IS_JOB_PENDING(job_ptr))
				continue;

			job_ptr->priority =
				_get_priority_internal(start_time, job_ptr);
			last_job_update = time(NULL);
			debug2("priority for job %u is now %u",
			       job_ptr->job_id, job_ptr->priority);
		}
		list_iterator_destroy(itr);
		unlock_slurmctld(job_write_lock);

	get_usage:
		/* now calculate all the normalized usage here */
		assoc_mgr_lock(&locks);
		_set_children_usage_efctv(
			assoc_mgr_root_assoc->usage->childern_list);
		assoc_mgr_unlock(&locks);

		last_ran = start_time;

		_write_last_decay_ran(last_ran, last_reset);

		running_decay = 0;
		slurm_mutex_unlock(&decay_lock);

		/* sleep for calc_period secs */
		tm.tm_sec += calc_period;
		tm.tm_isdst = -1;
		next_time = mktime(&tm);
		sleep((next_time-start_time));
		start_time = next_time;
		/* repeat ;) */
	}
	return NULL;
}
int main() {

    // create thread as 'joinable'
    pthread_attr_t tattr;
    pthread_attr_init(&tattr);
    pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);

    // set thread cancel state and type
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    int i = 0;
    char buffer[1024] = "";

    if (check_process_lock()) exit(1);

    // read database configuration
    if (read_config()) {
        exit(1);
    }

    // connect to database
    if (db_connect(&mysql, dbhost, dbuser, dbpass, dbname, dbport, NULL, 0) == 1) {
        exit(1);
    }

    // try another location
    if (get_server_id(SERVERCONFPATH)) {
        mor_log("Cannot read server configuration from: " SERVERCONFPATH " or server_id is not set", 0);
        exit(1);
    }

    // just to be sure
    if (server_id == 0) {
        mor_log("server_id is not set", 0);
        exit(1);
    }

    // starting sript
    mor_log("Starting Provider Check script", 1);

    // get provider data
    mor_log("Fetching provider data from database", 0);
    if (get_providers()) {
        exit(1);
    }

    if (prov_count == 0) {
        mor_log("No suitable providers were found", 0);
        exit(1);
    }

    mor_log("Checking provider availability", 0);
    for (i = 0; i < prov_count; i++) {

        prov_status = 0;

        pthread_create(&timeout, &tattr, timeout_thread, NULL);
        pthread_create(&pcheck, NULL, check_provider_status_thread, (void *)(intptr_t)i);
        pthread_join(timeout, NULL);

        if (prov_status == 0) {
            printf("Updating provider: [%d] %s:%d ALIVE = 0\n", prov[i].id, prov[i].server_ip, prov[i].port);
            sprintf(buffer, "Updating provider: [%d] %s:%d ALIVE = 0", prov[i].id, prov[i].server_ip, prov[i].port);
            mor_log(buffer, 0);
            if (update_provider_status(i, 0)) {
                exit(1);
            }
        } else {
            printf("Updating provider: [%d] %s:%d ALIVE = 1\n", prov[i].id, prov[i].server_ip, prov[i].port);
            sprintf(buffer, "Updating provider: [%d] %s:%d ALIVE = 1", prov[i].id, prov[i].server_ip, prov[i].port);
            mor_log(buffer, 0);
            if (update_provider_status(i, 1)) {
                exit(1);
            }
        }

    }

    unlink(TMP_FILE);

    return 0;

}
Example #19
0
int __po_hi_wait_initialization ()
{
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
   int cstate;
   if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &cstate) != 0)
   {
      __DEBUGMSG ("[MAIN] Cannot modify the cancel state\n");
   }

   if (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &cstate) != 0)
   {
      __DEBUGMSG ("[MAIN] Cannot modify the cancel type\n");
   }

  if (pthread_mutex_lock (&mutex_init) != 0)
  {
    __DEBUGMSG ("[MAIN] Unable to lock the mutex\n");
    return (__PO_HI_ERROR_PTHREAD_MUTEX);
  }

  __po_hi_initialized_tasks++;

  __DEBUGMSG ("[MAIN] %d task(s) initialized (total to init =%d)\n", __po_hi_initialized_tasks, __po_hi_nb_tasks_to_init);

  while (__po_hi_initialized_tasks < __po_hi_nb_tasks_to_init)
  {
      pthread_cond_wait (&cond_init, &mutex_init);
  }
  pthread_cond_broadcast (&cond_init);
  pthread_mutex_unlock (&mutex_init);

   __PO_HI_INSTRUMENTATION_VCD_INIT

  return (__PO_HI_SUCCESS);
#elif defined (_WIN32)
   EnterCriticalSection (&__po_hi_main_initialization_critical_section);

  __po_hi_initialized_tasks++;

  __DEBUGMSG ("[MAIN] %d task(s) initialized (total to init =%d)\n", __po_hi_initialized_tasks, __po_hi_nb_tasks_to_init);

  while (__po_hi_initialized_tasks < __po_hi_nb_tasks_to_init)
  {
      LeaveCriticalSection (&__po_hi_main_initialization_critical_section);
      WaitForSingleObject (__po_hi_main_initialization_event, INFINITE);
      EnterCriticalSection (&__po_hi_main_initialization_critical_section);
  }

  SetEvent (__po_hi_main_initialization_event);
  LeaveCriticalSection (&__po_hi_main_initialization_critical_section);
  return (__PO_HI_SUCCESS);

#elif defined (__PO_HI_RTEMS_CLASSIC_API)
  rtems_status_code ret;

  __DEBUGMSG ("[MAIN] Task wait for the barrier\n");
  ret = rtems_barrier_wait (__po_hi_main_initialization_barrier, RTEMS_WAIT);
  if (ret != RTEMS_SUCCESSFUL)
  {
     __DEBUGMSG ("[MAIN] Error while waiting for the barrier, return code=%d\n", ret);
     return (__PO_HI_ERROR_UNKNOWN);
  }
  __DEBUGMSG ("[MAIN] Task release the barrier\n");
  return (__PO_HI_SUCCESS);
#elif defined (XENO_NATIVE)
  int ret;

  if (main_task_id == rt_task_self ())
  {
     /*
      * Here, this function is called by the main thread (the one that executes
      * the main() function) so that we don't wait for the initialization of the
      * other tasks, we automatically pass through the function and immeditaly
      * return.
      */
     return (__PO_HI_SUCCESS);
  }

  ret = rt_mutex_acquire (&mutex_init, TM_INFINITE);
  if (ret != 0)
  {
   __DEBUGMSG ("[MAIN] Cannot acquire mutex (return code = %d)\n", ret);
    return (__PO_HI_ERROR_PTHREAD_MUTEX);
  }

  __po_hi_initialized_tasks++;

  __DEBUGMSG ("[MAIN] %d task(s) initialized (total to init =%d)\n", __po_hi_initialized_tasks, __po_hi_nb_tasks_to_init);

  while (__po_hi_initialized_tasks < __po_hi_nb_tasks_to_init)
  {
      rt_cond_wait (&cond_init, &mutex_init, TM_INFINITE);
  }
  rt_cond_broadcast (&cond_init);
  rt_mutex_release (&mutex_init);
  return (__PO_HI_SUCCESS);

#else
  return (__PO_HI_UNAVAILABLE);
#endif
}
Example #20
0
/*
*
* The main worker-thread for the i2c-dev device
* Enters an endless loop that waits for commands and
* executes them.
*
* Currently we only support GA-devices
*
*/
void *thr_sendrec_I2C_DEV(void *v)
{
    char msg[1000];
    ga_state_t gatmp;
    int last_cancel_state, last_cancel_type;

    bus_thread_t *btd = (bus_thread_t *) malloc(sizeof(bus_thread_t));
    if (btd == NULL)
        pthread_exit((void *) 1);
    btd->bus = (bus_t) v;
    btd->fd = -1;

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &last_cancel_state);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &last_cancel_type);

    /*register cleanup routine */
    pthread_cleanup_push((void *) end_bus_thread, (void *) btd);

    syslog_bus(btd->bus, DBG_INFO, "i2c-dev bus started (device =  %s).",
               buses[btd->bus].device.file.path);

    I2CDEV_DATA *data = buses[btd->bus].driverdata;
    int ga_reset_devices = data->ga_reset_devices;
    buses[btd->bus].watchdog = 1;

    /* command processing starts here */
    while (true) {

        /* process POWER changes */
        if (buses[btd->bus].power_changed == 1) {

            /* dummy select, power state is directly read by select_bus() */
            select_bus(0, btd->bus);
            buses[btd->bus].power_changed = 0;
            infoPower(btd->bus, msg);
            enqueueInfoMessage(msg);

            if ((ga_reset_devices == 1)
                && (buses[btd->bus].power_state == 1)) {
                reset_ga(btd->bus);
            }

        }

        /* do nothing, if power is off */
        if (buses[btd->bus].power_state == 0) {
            if (usleep(1000) == -1) {
                syslog_bus(btd->bus, DBG_ERROR,
                           "usleep() failed: %s (errno = %d)\n",
                           strerror(errno), errno);
            }
            continue;
        }

        buses[btd->bus].watchdog = 4;

        /* process GA commands */
        if (!queue_GA_isempty(btd->bus)) {
            dequeueNextGA(btd->bus, &gatmp);
            handle_i2c_set_ga(btd->bus, &gatmp);
            setGA(btd->bus, gatmp.id, gatmp);
            select_bus(0, btd->bus);
            buses[btd->bus].watchdog = 6;
        }
        if (usleep(1000) == -1) {
            syslog_bus(btd->bus, DBG_ERROR,
                       "usleep() failed: %s (errno = %d)\n",
                       strerror(errno), errno);
        }
    }

    /*run the cleanup routine */
    pthread_cleanup_pop(1);
    return NULL;
}
Example #21
0
//-----------------------------------------------------------------------------
// Main Entry
//-----------------------------------------------------------------------------
//int main(int argc, char **argv)
void * nhttpd_main_thread(void *data)
{
	//int argc = 1;
	//char **argv;
	//bool do_fork = false;

	pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);

	aprintf("Webserver %s tid %ld\n", WEBSERVERNAME, syscall(__NR_gettid));
	yhttpd = new Cyhttpd();

//CLogging::getInstance()->setDebug(true);
//CLogging::getInstance()->LogLevel = 9;
	if(!yhttpd)
	{
		aprintf("Error initializing WebServer\n");
		return (void *) EXIT_FAILURE;
	}
	yhttpd->flag_threading_off = true;
#if 0
	for (int i = 1; i < argc; i++)
	{
		if ((!strncmp(argv[i], "-d", 2)) || (!strncmp(argv[i], "--debug", 7)))
		{
			CLogging::getInstance()->setDebug(true);
			do_fork = false;
		}
		else if ((!strncmp(argv[i], "-f", 2)) || (!strncmp(argv[i], "--fork", 6)) || (!strncmp(argv[i], "-nf", 3)))
		{
			do_fork = false;
		}
		else if ((!strncmp(argv[i], "-h", 2)) || (!strncmp(argv[i], "--help", 6)))
		{
			yhttpd->usage(stdout);
			return (void *) EXIT_SUCCESS;
		}
		else if ((!strncmp(argv[i], "-v", 2)) || (!strncmp(argv[i],"--version", 9)))
		{
			yhttpd->version(stdout);
			return (void *) EXIT_SUCCESS;
		}
		else if ((!strncmp(argv[i], "-t", 2)) || (!strncmp(argv[i],"--thread-off", 12)))
		{
			yhttpd->flag_threading_off = true;
		}
		else if ((!strncmp(argv[i], "-l", 2)) )
		{
			if(argv[i][2] >= '0' && argv[i][2] <= '9')
				CLogging::getInstance()->LogLevel = (argv[i][2]-'0');
		}
		else
		{
			yhttpd->usage(stderr);
			return (void *) EXIT_FAILURE;
		}
	}
	// setup signal catching (subscribing)
	//signal(SIGPIPE, sig_catch);
	//signal(SIGINT, sig_catch);
	//signal(SIGHUP, sig_catch);
	//signal(SIGUSR1, sig_catch);
	//signal(SIGTERM, sig_catch);
    	//signal(SIGCLD, SIG_IGN);
//	signal(SIGALRM, sig_catch);
#endif

	yhttpd->hooks_attach();
	yhttpd->ReadConfig();
	if(yhttpd->Configure())
	{
		// Start Webserver: fork ist if not in debug mode
		aprintf("Webserver starting...\n");
		dprintf("Start in Debug-Mode\n"); // non forked debugging loop
		
		yhttpd->run();
	}
	delete yhttpd;
	
	aprintf("Main end\n");
	return (void *) EXIT_SUCCESS;
}
Example #22
0
static gpointer
_mp_app_inotify_watch_thread(gpointer user_data)
{
	mp_inotify_t *handle = (mp_inotify_t *) user_data;
	int oldtype = 0;

	mp_retvm_if(handle == NULL, NULL, "handle is NULL");
	DEBUG_TRACE("Create _mp_app_inotify_watch_thread!!! ");

	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);

	while (1)
	{
		ssize_t len = 0;
		ssize_t i = 0;
		char event_buff[MP_EVENT_BUF_LEN] = { 0, };

		if (handle->fd < 0)
		{
			ERROR_TRACE("fd is not a vaild one");
			pthread_exit(NULL);
		}

		len = read(handle->fd, event_buff, sizeof(event_buff) - 1);
		if (len <= 0 || len > sizeof(event_buff) - 1)
		{

		}

		while (i < len)
		{
			struct inotify_event *pevent = (struct inotify_event *)&event_buff[i];
			mp_inotify_event s_event = MP_INOTI_NONE;

			if (pevent->len && strncmp(pevent->name, ".", 1) == 0)
			{
				s_event = MP_INOTI_NONE;
			}
			else if (pevent->mask & IN_ISDIR)	//directory
			{
				/*
				   if (pevent->mask & IN_DELETE_SELF)
				   s_event = MP_INOTI_DELETE_SELF;

				   if (pevent->mask & IN_MOVE_SELF)
				   s_event = MP_INOTI_MOVE_SELF;

				   if (pevent->mask & IN_CREATE)
				   s_event = MP_INOTI_CREATE;

				   if (pevent->mask & IN_DELETE)
				   s_event = MP_INOTI_DELETE;

				   if (pevent->mask & IN_MOVED_FROM)
				   s_event = MP_INOTI_MOVE_OUT;

				   if (pevent->mask & IN_MOVED_TO)
				   s_event = MP_INOTI_MOVE_IN;
				 */
			}
			else	//file
			{
				if (pevent->mask & IN_CREATE)
				{
					s_event = MP_INOTI_NONE;
					handle->prev_event = IN_CREATE;
				}

				if (pevent->mask & IN_CLOSE_WRITE)
				{
					if (handle->prev_event == IN_CREATE)
					{
						s_event = MP_INOTI_CREATE;
					}
					handle->prev_event = MP_INOTI_NONE;
				}

				if (pevent->mask & IN_DELETE)
					s_event = MP_INOTI_DELETE;

				if (pevent->mask & IN_MODIFY)
				{
					s_event = MP_INOTI_MODIFY;
				}

				if (pevent->mask & IN_MOVED_TO)
				{
					s_event = MP_INOTI_MOVE_OUT;
				}
			}

			if (s_event != MP_INOTI_NONE)
			{
				pthread_cleanup_push(_mp_app_inotify_thread_clean_up, (void *)&mp_noti_lock);
				pthread_mutex_lock(&mp_noti_lock);
				if (handle->callback)
				{
					handle->callback(s_event, (pevent->len) ? pevent->name : NULL, handle->u_data);
				}
				pthread_mutex_unlock(&mp_noti_lock);
				pthread_cleanup_pop(0);
			}

			i += sizeof(struct inotify_event) + pevent->len;

			if (i >= MP_EVENT_BUF_LEN)
				break;
		}
	}

	DEBUG_TRACE("end _mp_app_inotify_watch_thread!!! ");

	return NULL;
}
Example #23
0
void *tc_main(void *ptr) {
    struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;

    info("TC thread created with task id %d", gettid());

    if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
        error("Cannot set pthread cancel type to DEFERRED.");

    if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
        error("Cannot set pthread cancel state to ENABLE.");

    struct rusage thread;
    RRDSET *stcpu = NULL, *sttime = NULL;

    char buffer[TC_LINE_MAX+1] = "";
    char *words[MAX_WORDS] = { NULL };

    uint32_t BEGIN_HASH = simple_hash("BEGIN");
    uint32_t END_HASH = simple_hash("END");
    uint32_t QDISC_HASH = simple_hash("qdisc");
    uint32_t CLASS_HASH = simple_hash("class");
    uint32_t SENT_HASH = simple_hash("Sent");
    uint32_t LENDED_HASH = simple_hash("lended:");
    uint32_t TOKENS_HASH = simple_hash("tokens:");
    uint32_t SETDEVICENAME_HASH = simple_hash("SETDEVICENAME");
    uint32_t SETDEVICEGROUP_HASH = simple_hash("SETDEVICEGROUP");
    uint32_t SETCLASSNAME_HASH = simple_hash("SETCLASSNAME");
    uint32_t WORKTIME_HASH = simple_hash("WORKTIME");
#ifdef DETACH_PLUGINS_FROM_NETDATA
    uint32_t MYPID_HASH = simple_hash("MYPID");
#endif
    uint32_t first_hash;

    snprintfz(buffer, TC_LINE_MAX, "%s/tc-qos-helper.sh", netdata_configured_plugins_dir);
    char *tc_script = config_get("plugin:tc", "script to run to get tc values", buffer);
    
    for(;1;) {
        if(unlikely(netdata_exit)) break;

        FILE *fp;
        struct tc_device *device = NULL;
        struct tc_class *class = NULL;

        snprintfz(buffer, TC_LINE_MAX, "exec %s %d", tc_script, rrd_update_every);
        debug(D_TC_LOOP, "executing '%s'", buffer);

        fp = mypopen(buffer, (pid_t *)&tc_child_pid);
        if(unlikely(!fp)) {
            error("TC: Cannot popen(\"%s\", \"r\").", buffer);
            goto cleanup;
        }

        while(fgets(buffer, TC_LINE_MAX, fp) != NULL) {
            if(unlikely(netdata_exit)) break;

            buffer[TC_LINE_MAX] = '\0';
            // debug(D_TC_LOOP, "TC: read '%s'", buffer);

            tc_split_words(buffer, words, MAX_WORDS);

            if(unlikely(!words[0] || !*words[0])) {
                // debug(D_TC_LOOP, "empty line");
                continue;
            }
            // else debug(D_TC_LOOP, "First word is '%s'", words[0]);

            first_hash = simple_hash(words[0]);

            if(unlikely(device && ((first_hash == CLASS_HASH && strcmp(words[0], "class") == 0) ||  (first_hash == QDISC_HASH && strcmp(words[0], "qdisc") == 0)))) {
                // debug(D_TC_LOOP, "CLASS line on class id='%s', parent='%s', parentid='%s', leaf='%s', leafid='%s'", words[2], words[3], words[4], words[5], words[6]);

                char *type     = words[1];  // the class/qdisc type: htb, fq_codel, etc
                char *id       = words[2];  // the class/qdisc major:minor
                char *parent   = words[3];  // the word 'parent' or 'root'
                char *parentid = words[4];  // parentid
                char *leaf     = words[5];  // the word 'leaf'
                char *leafid   = words[6];  // leafid

                int parent_is_root = 0;
                int parent_is_parent = 0;
                if(likely(parent)) {
                    parent_is_parent = !strcmp(parent, "parent");

                    if(!parent_is_parent)
                        parent_is_root = !strcmp(parent, "root");
                }

                if(likely(type && id && (parent_is_root || parent_is_parent))) {
                    char qdisc = 0;

                    if(first_hash == QDISC_HASH) {
                        qdisc = 1;

                        if(!strcmp(type, "ingress")) {
                            // we don't want to get the ingress qdisc
                            // there should be an IFB interface for this

                            class = NULL;
                            continue;
                        }

                        if(parent_is_parent && parentid) {
                            // eliminate the minor number from parentid
                            // why: parentid is the id of the parent class
                            // but major: is also the id of the parent qdisc

                            char *s = parentid;
                            while(*s && *s != ':') s++;
                            if(*s == ':') s[1] = '\0';
                        }
                    }

                    if(parent_is_root) {
                        parentid = NULL;
                        leafid = NULL;
                    }
                    else if(!leaf || strcmp(leaf, "leaf") != 0)
                        leafid = NULL;

                    char leafbuf[20 + 1] = "";
                    if(leafid && leafid[strlen(leafid) - 1] == ':') {
                        strncpyz(leafbuf, leafid, 20 - 1);
                        strcat(leafbuf, "1");
                        leafid = leafbuf;
                    }

                    class = tc_class_add(device, id, qdisc, parentid, leafid);
                }
                else {
Example #24
0
/* Process incoming RPCs. Meant to execute as a pthread */
extern void *rpc_mgr(void *no_data)
{
	pthread_attr_t thread_attr_rpc_req;
	slurm_fd_t sockfd, newsockfd;
	int i, retry_cnt, sigarray[] = {SIGUSR1, 0};
	slurm_addr_t cli_addr;
	slurmdbd_conn_t *conn_arg = NULL;

	slurm_mutex_lock(&thread_count_lock);
	master_thread_id = pthread_self();
	slurm_mutex_unlock(&thread_count_lock);

	(void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	(void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	/* threads to process individual RPC's are detached */
	slurm_attr_init(&thread_attr_rpc_req);
	if (pthread_attr_setdetachstate
	    (&thread_attr_rpc_req, PTHREAD_CREATE_DETACHED))
		fatal("pthread_attr_setdetachstate %m");

	/* initialize port for RPCs */
	if ((sockfd = slurm_init_msg_engine_port(get_dbd_port()))
	    == SLURM_SOCKET_ERROR)
		fatal("slurm_init_msg_engine_port error %m");

	/* Prepare to catch SIGUSR1 to interrupt accept().
	 * This signal is generated by the slurmdbd signal
	 * handler thread upon receipt of SIGABRT, SIGINT,
	 * or SIGTERM. That thread does all processing of
	 * all signals. */
	xsignal(SIGUSR1, _sig_handler);
	xsignal_unblock(sigarray);

	/*
	 * Process incoming RPCs until told to shutdown
	 */
	while ((i = _wait_for_server_thread()) >= 0) {
		/*
		 * accept needed for stream implementation is a no-op in
		 * message implementation that just passes sockfd to newsockfd
		 */
		if ((newsockfd = slurm_accept_msg_conn(sockfd,
						       &cli_addr)) ==
		    SLURM_SOCKET_ERROR) {
			_free_server_thread((pthread_t) 0);
			if (errno != EINTR)
				error("slurm_accept_msg_conn: %m");
			continue;
		}
		fd_set_nonblocking(newsockfd);

		conn_arg = xmalloc(sizeof(slurmdbd_conn_t));
		conn_arg->newsockfd = newsockfd;
		slurm_get_ip_str(&cli_addr, &conn_arg->orig_port,
				 conn_arg->ip, sizeof(conn_arg->ip));
		retry_cnt = 0;
		while (pthread_create(&slave_thread_id[i],
				      &thread_attr_rpc_req,
				      _service_connection,
				      (void *) conn_arg)) {
			if (retry_cnt > 0) {
				error("pthread_create failure, "
				      "aborting RPC: %m");
				close(newsockfd);
				break;
			}
			error("pthread_create failure: %m");
			retry_cnt++;
			usleep(1000);	/* retry in 1 msec */
		}
	}

	debug3("rpc_mgr shutting down");
	slurm_attr_destroy(&thread_attr_rpc_req);
	(void) slurm_shutdown_msg_engine(sockfd);
	_wait_for_thread_fini();
	pthread_exit((void *) 0);
	return NULL;
}
Example #25
0
/* nb: returns a negative errno via ERR_PTR */
static void *scrub_progress_cycle(void *ctx)
{
	int ret = 0;
	int  perr = 0;	/* positive / pthread error returns */
	int old;
	int i;
	char fsid[BTRFS_UUID_UNPARSED_SIZE];
	struct scrub_progress *sp;
	struct scrub_progress *sp_last;
	struct scrub_progress *sp_shared;
	struct timeval tv;
	struct scrub_progress_cycle *spc = ctx;
	int ndev = spc->fi->num_devices;
	int this = 1;
	int last = 0;
	int peer_fd = -1;
	struct pollfd accept_poll_fd = {
		.fd = spc->prg_fd,
		.events = POLLIN,
		.revents = 0,
	};
	struct pollfd write_poll_fd = {
		.events = POLLOUT,
		.revents = 0,
	};
	struct sockaddr_un peer;
	socklen_t peer_size = sizeof(peer);

	perr = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
	if (perr)
		goto out;

	uuid_unparse(spc->fi->fsid, fsid);

	for (i = 0; i < ndev; ++i) {
		sp = &spc->progress[i];
		sp_last = &spc->progress[i + ndev];
		sp_shared = &spc->shared_progress[i];
		sp->scrub_args.devid = sp_last->scrub_args.devid =
						sp_shared->scrub_args.devid;
		sp->fd = sp_last->fd = spc->fdmnt;
		sp->stats.t_start = sp_last->stats.t_start =
						sp_shared->stats.t_start;
		sp->resumed = sp_last->resumed = sp_shared->resumed;
		sp->skip = sp_last->skip = sp_shared->skip;
		sp->stats.finished = sp_last->stats.finished =
						sp_shared->stats.finished;
	}

	while (1) {
		ret = poll(&accept_poll_fd, 1, 5 * 1000);
		if (ret == -1) {
			ret = -errno;
			goto out;
		}
		if (ret)
			peer_fd = accept(spc->prg_fd, (struct sockaddr *)&peer,
					 &peer_size);
		gettimeofday(&tv, NULL);
		this = (this + 1)%2;
		last = (last + 1)%2;
		for (i = 0; i < ndev; ++i) {
			sp = &spc->progress[this * ndev + i];
			sp_last = &spc->progress[last * ndev + i];
			sp_shared = &spc->shared_progress[i];
			if (sp->stats.finished)
				continue;
			progress_one_dev(sp);
			sp->stats.duration = tv.tv_sec - sp->stats.t_start;
			if (!sp->ret)
				continue;
			if (sp->ioctl_errno != ENOTCONN &&
			    sp->ioctl_errno != ENODEV) {
				ret = -sp->ioctl_errno;
				goto out;
			}
			/*
			 * scrub finished or device removed, check the
			 * finished flag. if unset, just use the last
			 * result we got for the current write and go
			 * on. flag should be set on next cycle, then.
			 */
			perr = pthread_setcancelstate(
					PTHREAD_CANCEL_DISABLE, &old);
			if (perr)
				goto out;
			perr = pthread_mutex_lock(&sp_shared->progress_mutex);
			if (perr)
				goto out;
			if (!sp_shared->stats.finished) {
				perr = pthread_mutex_unlock(
						&sp_shared->progress_mutex);
				if (perr)
					goto out;
				perr = pthread_setcancelstate(
						PTHREAD_CANCEL_ENABLE, &old);
				if (perr)
					goto out;
				memcpy(sp, sp_last, sizeof(*sp));
				continue;
			}
			perr = pthread_mutex_unlock(&sp_shared->progress_mutex);
			if (perr)
				goto out;
			perr = pthread_setcancelstate(
					PTHREAD_CANCEL_ENABLE, &old);
			if (perr)
				goto out;
			memcpy(sp, sp_shared, sizeof(*sp));
			memcpy(sp_last, sp_shared, sizeof(*sp));
		}
		if (peer_fd != -1) {
			write_poll_fd.fd = peer_fd;
			ret = poll(&write_poll_fd, 1, 0);
			if (ret == -1) {
				ret = -errno;
				goto out;
			}
			if (ret) {
				ret = scrub_write_file(
					peer_fd, fsid,
					&spc->progress[this * ndev], ndev);
				if (ret)
					goto out;
			}
			close(peer_fd);
			peer_fd = -1;
		}
		if (!spc->do_record)
			continue;
		ret = scrub_write_progress(spc->write_mutex, fsid,
					   &spc->progress[this * ndev], ndev);
		if (ret)
			goto out;
	}
out:
	if (peer_fd != -1)
		close(peer_fd);
	if (perr)
		ret = -perr;
	return ERR_PTR(ret);
}

static struct scrub_file_record *last_dev_scrub(
		struct scrub_file_record *const *const past_scrubs, u64 devid)
{
	int i;

	if (!past_scrubs || IS_ERR(past_scrubs))
		return NULL;

	for (i = 0; past_scrubs[i]; ++i)
		if (past_scrubs[i]->devid == devid)
			return past_scrubs[i];

	return NULL;
}

static int mkdir_p(char *path)
{
	int i;
	int ret;

	for (i = 1; i < strlen(path); ++i) {
		if (path[i] != '/')
			continue;
		path[i] = '\0';
		ret = mkdir(path, 0777);
		if (ret && errno != EEXIST)
			return -errno;
		path[i] = '/';
	}

	return 0;
}
Example #26
0
/* _rollup_handler - Process rollup duties */
static void *_rollup_handler(void *db_conn)
{
	time_t start_time = time(NULL);
	time_t next_time;
/* 	int sigarray[] = {SIGUSR1, 0}; */
	struct tm tm;
	rollup_stats_t rollup_stats;
	int i;

	(void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	(void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	if (!slurm_localtime_r(&start_time, &tm)) {
		fatal("Couldn't get localtime for rollup handler %ld",
		      (long)start_time);
		return NULL;
	}

	while (1) {
		if (!db_conn)
			break;
		/* run the roll up */
		memset(&rollup_stats, 0, sizeof(rollup_stats_t));
		slurm_mutex_lock(&rollup_lock);
		running_rollup = 1;
		debug2("running rollup at %s", slurm_ctime2(&start_time));
		acct_storage_g_roll_usage(db_conn, 0, 0, 1, &rollup_stats);
		acct_storage_g_commit(db_conn, 1);
		running_rollup = 0;
		slurm_mutex_unlock(&rollup_lock);

		slurm_mutex_lock(&rpc_mutex);
		for (i = 0; i < ROLLUP_COUNT; i++) {
			if (rollup_stats.rollup_time[i] == 0)
				continue;
			rpc_stats.rollup_count[i]++;
			rpc_stats.rollup_time[i] +=
				rollup_stats.rollup_time[i];
			rpc_stats.rollup_max_time[i] =
				MAX(rpc_stats.rollup_max_time[i],
				    rollup_stats.rollup_time[i]);
		}
		slurm_mutex_unlock(&rpc_mutex);

		/* get the time now we have rolled usage */
		start_time = time(NULL);

		if (!slurm_localtime_r(&start_time, &tm)) {
			fatal("Couldn't get localtime for rollup handler %ld",
			      (long)start_time);
			return NULL;
		}

		/* sleep until the next hour */
		tm.tm_sec = 0;
		tm.tm_min = 0;
		tm.tm_hour++;
		tm.tm_isdst = -1;
		next_time = slurm_mktime(&tm);

		sleep((next_time - start_time));

		start_time = next_time;

		/* Just in case some new uids were added to the system
		   pick them up here. */
		assoc_mgr_set_missing_uids();
		/* repeat ;) */

	}

	return NULL;
}
Example #27
0
void *nfacct_main(void *ptr) {
    if(ptr) { ; }

    info("NFACCT thread created with task id %d", gettid());

    if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
        error("nfacct.plugin: Cannot set pthread cancel type to DEFERRED.");

    if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
        error("nfacct.plugin: Cannot set pthread cancel state to ENABLE.");

    char buf[MNL_SOCKET_BUFFER_SIZE];
    struct mnl_socket *nl = NULL;
    struct nlmsghdr *nlh = NULL;
    unsigned int seq = 0, portid = 0;

    seq = time(NULL) - 1;

    nl  = mnl_socket_open(NETLINK_NETFILTER);
    if(!nl) {
        error("nfacct.plugin: mnl_socket_open() failed");
        pthread_exit(NULL);
        return NULL;
    }

    if(mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
        mnl_socket_close(nl);
        error("nfacct.plugin: mnl_socket_bind() failed");
        pthread_exit(NULL);
        return NULL;
    }
    portid = mnl_socket_get_portid(nl);

    // ------------------------------------------------------------------------

    struct timeval last, now;
    unsigned long long usec = 0, susec = 0;
    RRDSET *st = NULL;

    gettimeofday(&last, NULL);

    // ------------------------------------------------------------------------

    while(1) {
        if(unlikely(netdata_exit)) break;

        seq++;

        nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, seq);
        if(!nlh) {
            mnl_socket_close(nl);
            error("nfacct.plugin: nfacct_nlmsg_build_hdr() failed");
            pthread_exit(NULL);
            return NULL;
        }

        if(mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
            error("nfacct.plugin: mnl_socket_send");
            pthread_exit(NULL);
            return NULL;
        }

        if(nfacct_list) nfacct_list->len = 0;

        int ret;
        while((ret = mnl_socket_recvfrom(nl, buf, sizeof(buf))) > 0) {
            if((ret = mnl_cb_run(buf, ret, seq, portid, nfacct_callback, NULL)) <= 0) break;
        }

        if (ret == -1) {
            error("nfacct.plugin: error communicating with kernel.");
            pthread_exit(NULL);
            return NULL;
        }

        // --------------------------------------------------------------------

        gettimeofday(&now, NULL);
        usec = usec_dt(&now, &last) - susec;
        debug(D_NFACCT_LOOP, "nfacct.plugin: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);

        if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec;
        else susec = rrd_update_every * 1000000ULL / 2ULL;


        // --------------------------------------------------------------------

        if(nfacct_list && nfacct_list->len) {
            int i;

            st = rrdset_find_bytype("netfilter", "nfacct_packets");
            if(!st) {
                st = rrdset_create("netfilter", "nfacct_packets", NULL, "nfacct", NULL, "Netfilter Accounting Packets", "packets/s", 3206, rrd_update_every, RRDSET_TYPE_STACKED);

                for(i = 0; i < nfacct_list->len ; i++)
                    rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL);
            }
            else rrdset_next(st);

            for(i = 0; i < nfacct_list->len ; i++) {
                RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name);

                if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL);
                if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].pkts);
            }

            rrdset_done(st);

            // ----------------------------------------------------------------

            st = rrdset_find_bytype("netfilter", "nfacct_bytes");
            if(!st) {
                st = rrdset_create("netfilter", "nfacct_bytes", NULL, "nfacct", NULL, "Netfilter Accounting Bandwidth", "kilobytes/s", 3207, rrd_update_every, RRDSET_TYPE_STACKED);

                for(i = 0; i < nfacct_list->len ; i++)
                    rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL);
            }
            else rrdset_next(st);

            for(i = 0; i < nfacct_list->len ; i++) {
                RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name);

                if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL);
                if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].bytes);
            }

            rrdset_done(st);
        }

        // --------------------------------------------------------------------

        usleep(susec);

        // copy current to last
        bcopy(&now, &last, sizeof(struct timeval));
    }

    mnl_socket_close(nl);
    pthread_exit(NULL);
    return NULL;
}
Example #28
0
//------------------------------------------------------------------------------
void* keycontrol_main(void *Args)
{
  //<simulation>
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
  PIC_ARG *Simul=(PIC_ARG*)Args; 
  Simul->robot->data[Simul->my_nbr].destX = _POS_INIT_X;
  Simul->robot->data[Simul->my_nbr].destY = _POS_INIT_Y;
  Simul->robot->data[Simul->my_nbr].destA = _POS_INIT_A;        
  //</simulation> 
  
  double posX,posY,angle;     // la position
  
  SDL_Event event;
  bool key[6]={false,false,false,false,false,false};  //0-up 1-down 2-left 3-right
  double vitesse=1.;
  double u[2];
  
  
  //Initialisation du calcul de la position
  posX  = _POS_INIT_X;
  posY  = _POS_INIT_Y;
  angle = _POS_INIT_A;
  
  long codeuse[2];
  codeuse[0]=get_input(Simul,CODER,0);
  codeuse[1]=get_input(Simul,CODER,1);    
  long gauche = codeuse[0], dgauche;
  long droite = codeuse[1], ddroite;
  double distgauche, distdroite, dalpha, dx, dy;
  
  printf("\n\
You're using the keyboard!\n\
 - press 'a'/'q' to move faster/slower\n\
 - press 'z'/'s' to open/close the clamp\n\
 - press 'r'/'f'/'v' to make the belt roll outside/stop/roll inside\n\
 - press 't'/'g'/'b' to move the clamp fowards/middle/backwards\n\
 - press 'y'/'n' to move the clamp up/down\n\n\
 "); 
  
  while(!is_SDL_ready()) {pthread_yield();}
  while(1)
  { 
    SDL_PeepEvents(&event,1,SDL_GETEVENT,SDL_ALLEVENTS);
    if(event.type==SDL_KEYDOWN)
      switch(event.key.keysym.sym)
      {
        case 273: key[0]=true; break;   // up
        case 274: key[1]=true; break;   // down
        case 276: key[2]=true; break;   // left
        case 275: key[3]=true; break;   // right 
        case 97:  key[4]=true; break;   // a (vitesse+)
        case 113: key[5]=true; break;   // q (vitesse-)  
        case 114: set_output(Simul,BELT,0,1); break;  // r
        case 102: set_output(Simul,BELT,0,0); break;    // f
        case 118: set_output(Simul,BELT,0,-1); break; // v       
        case 116: set_output(Simul,HPOS,0,posClampFront); break;     // t
        case 103: set_output(Simul,HPOS,0,posClampMiddle); break;     // g        
        case 98:  set_output(Simul,HPOS,0,posClampBack); break;     // b
        case 121: set_output(Simul,VPOS,0,400); break;    // y
        case 110:  set_output(Simul,VPOS,0,-100); break; // n        
        case 122: set_output(Simul,CLAMP,0,stClampOpen); break;  // z
        case 115: set_output(Simul,CLAMP,0,stClampClosed); printf("%f\n",((float)MAX_DIST_CAPT) - ((float)Simul->robot->dist_captors[0].measure()) * MAX_DIST_CAPT / ((float)RANGE_DIST_CAPT));  break;  // s 
        default: break; //printf("%d\n",event.key.keysym.sym);
      }
    if(event.type==SDL_KEYUP)
      switch(event.key.keysym.sym)
      {
        case 273: key[0]=false; break;  // up
        case 274: key[1]=false; break;  // down
        case 276: key[2]=false; break;  // left
        case 275: key[3]=false; break;  // right    
        case 97: 
        if(key[4])
        {
          vitesse+=0.1; 
          if(vitesse>1.) vitesse=1.;
          key[4]=false;
        }
        break;
        case 113:
        if(key[5])
        {
          vitesse-=0.1;
          if(vitesse<0.) vitesse=0.;
          key[5]=false;
        }
        break;           
        default: break;                
      }
    if(event.type==SDL_KEYDOWN || event.type==SDL_KEYUP)     
    {
      u[0]=0.;
      u[1]=0.;             
      if(key[0]) {u[0]+=1.; u[1]+=1.;}  // up
      if(key[1]) {u[0]-=1.; u[1]-=1.;}  // down
      if(key[2])  // left
      {
        if(u[0]!=0.) u[0]/=2.; else {u[0]=-1.; u[1]=1.;}
      }
      if(key[3])  // right
      {
        if(u[1]!=0.) u[1]/=2.; else {u[0]=1.; u[1]=-1.;}
      }
      int UG=vitesse*u[0]*((double)RANGE_MOTOR);
      int UD=vitesse*u[1]*((double)RANGE_MOTOR);
      set_output(Simul,MOTORS,0,UG);
      set_output(Simul,MOTORS,1,UD);    
      event.type=!(SDL_KEYDOWN|SDL_KEYUP);       
    }   
      
    //Calcul de la position
    codeuse[0]=get_input(Simul,CODER,0);
    codeuse[1]=get_input(Simul,CODER,1);
    
    dgauche = codeuse[0] - gauche;
    ddroite = codeuse[1] - droite;  
    distgauche = dgauche * _RAYON_ROUE  / (_FREQ_CODER * _MOTOR_K);
    distdroite = ddroite * _RAYON_ROUE  / (_FREQ_CODER * _MOTOR_K);
    dalpha=(distgauche-distdroite) / _ROUE_Y;
    dx = (distdroite+distgauche)/2.*cos(angle);
    dy = (distdroite+distgauche)/2.*sin(angle);
    posX+=dx;//+_ROUE_X*(cos(angle)-cos(angle+dalpha));   
    posY+=dy;//+_ROUE_X*(sin(angle)-sin(angle+dalpha));
    angle+=dalpha;    
    gauche = codeuse[0]; 
  	droite = codeuse[1];

    //<simulation>
    Simul->robot->data[Simul->my_nbr].posX=posX;
    Simul->robot->data[Simul->my_nbr].posY=posY;    
    Simul->robot->data[Simul->my_nbr].angle=angle;    
    pthread_barrier_wait(Simul->barrier);
    pthread_barrier_wait(Simul->barrier);    
    if(*Simul->STOP)
    {
      *Simul->alive_thread = *Simul->alive_thread-1;
      break;
    }
    //</simulation>
  }
  return NULL;
Example #29
0
static void *
tpool_worker(void *arg)
{
	tpool_t *tpool = (tpool_t *)arg;
	int elapsed;
	tpool_job_t *job;
	void (*func)(void *);
	tpool_active_t active;

	sig_mutex_lock(&tpool->tp_mutex);
	pthread_cleanup_push(worker_cleanup, tpool);

	/*
	 * This is the worker's main loop.
	 * It will only be left if a timeout or an error has occured.
	 */
	active.tpa_tid = pthread_self();
	for (;;) {
		elapsed = 0;
		tpool->tp_idle++;
		if (tpool->tp_flags & TP_WAIT)
			notify_waiters(tpool);
		while ((tpool->tp_head == NULL ||
		    (tpool->tp_flags & TP_SUSPEND)) &&
		    !(tpool->tp_flags & (TP_DESTROY | TP_ABANDON))) {
			if (tpool->tp_current <= tpool->tp_minimum ||
			    tpool->tp_linger == 0) {
				(void) sig_cond_wait(&tpool->tp_workcv,
				    &tpool->tp_mutex);
			} else {
				timestruc_t timeout;

				timeout.tv_sec = tpool->tp_linger;
				timeout.tv_nsec = 0;
				if (sig_cond_reltimedwait(&tpool->tp_workcv,
				    &tpool->tp_mutex, &timeout) != 0) {
					elapsed = 1;
					break;
				}
			}
		}
		tpool->tp_idle--;
		if (tpool->tp_flags & TP_DESTROY)
			break;
		if (tpool->tp_flags & TP_ABANDON) {
			/* can't abandon a suspended pool */
			if (tpool->tp_flags & TP_SUSPEND) {
				tpool->tp_flags &= ~TP_SUSPEND;
				(void) cond_broadcast(&tpool->tp_workcv);
			}
			if (tpool->tp_head == NULL)
				break;
		}
		if ((job = tpool->tp_head) != NULL &&
		    !(tpool->tp_flags & TP_SUSPEND)) {
			elapsed = 0;
			func = job->tpj_func;
			arg = job->tpj_arg;
			tpool->tp_head = job->tpj_next;
			if (job == tpool->tp_tail)
				tpool->tp_tail = NULL;
			tpool->tp_njobs--;
			active.tpa_next = tpool->tp_active;
			tpool->tp_active = &active;
			sig_mutex_unlock(&tpool->tp_mutex);
			pthread_cleanup_push(job_cleanup, tpool);
			lfree(job, sizeof (*job));
			/*
			 * Call the specified function.
			 */
			func(arg);
			/*
			 * We don't know what this thread has been doing,
			 * so we reset its signal mask and cancellation
			 * state back to the initial values.
			 */
			(void) pthread_sigmask(SIG_SETMASK, &maskset, NULL);
			(void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,
			    NULL);
			(void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
			    NULL);
			pthread_cleanup_pop(1);
		}
		if (elapsed && tpool->tp_current > tpool->tp_minimum) {
			/*
			 * We timed out and there is no work to be done
			 * and the number of workers exceeds the minimum.
			 * Exit now to reduce the size of the pool.
			 */
			break;
		}
	}
	pthread_cleanup_pop(1);
	return (arg);
}
Example #30
0
/*
 * Uptime thread...
 */
void *
th_uptime(void *arg)
{
   int ret,n;
   struct timeval timeout;
   sigset_t mask;

write_log(0,"\n th_uptime thread = %d\n",(int)pthread_self());

   sigfillset(&mask);

   if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
   {
      thread_error("th_uptime pthread_sigmask()",errno);
      th_uptime_exit();
   }

   if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL))
   {
      thread_error("th_uptime pthread_setcancelstate()",errno);
      th_uptime_exit();
   }

   pthread_cleanup_push( &th_uptime_clean, (void *)NULL );
   
   if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
   {
      thread_error("th_uptime pthread_setcancelstate()",errno);
      th_uptime_exit();
   }

   if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
   {
      n=errno;
      pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
      thread_error("th_uptime pthread_setcanceltype()",n);
      th_uptime_exit();
   }

   while(1)
   {
      timeout.tv_sec  = 1;
      timeout.tv_usec = 0;

      if ( (ret=select( 0, NULL, NULL, NULL, &timeout ) ) == -1 )
      {
         n=errno;
         thread_error("th_uptime select()",n);
         continue;
      }

      if ( !ret )  /* Timeout, update uptime... */
         uptime++; 
   }

   pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);         

   pthread_cleanup_pop(0);

   return (NULL);
}