def main():
	global flagTerminate
        global beanstalk
	global logger

	logger = setupLogger()

 	# define a Handler which writes INFO messages or higher to the sys.stderr
	console = logging.StreamHandler()
	console.setLevel(logging.INFO)
	# set a format which is simpler for console use
	formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
	# tell the handler to use this format
	console.setFormatter(formatter)
	# add the handler to the root logger
	logging.getLogger().addHandler(console)

	random.seed()

	pool = ActivePool()
	assignments = pool.mgr.dict()
	count = pool.mgr.Value('i', 0)
	ADBFAILCOUNT = pool.mgr.Value('i', 0)

	VMs = pool.mgr.dict()

	s = multiprocessing.Semaphore(NUMACTIVEWORKERS)
	q = multiprocessing.Queue()
	r = multiprocessing.Queue()
	results = []
	al = multiprocessing.RLock()
	vml = multiprocessing.RLock()
	cl = multiprocessing.RLock()

	get_VMs(VMs)
	list_VMs(VMs)
	#make sure any pcaps are killed and we are starting with a clean filesystem

	for i in range(30):
		#q.put("item " + str(i) + " content")
		q.put("live" + str(i))
		

	#adb ports are 5554 - 5584, only even	
	port = ADBPORT
	jobs = [
		multiprocessing.Process(target=worker, name=str(i), args=(s, pool, q, "hi", VMs, vml, str(port+(i*2)), count, al, r, ADBFAILCOUNT))
		for i in range(NUMWORKERS)
		]

	for j in jobs:
		logger.info( "starting worker %s" % j.name)
		j.start()

#	for j in jobs:
#		j.join()
#		logger.info( 'Now running: %s' % str(pool))

	#make the connection after the child spawning, each child makes thier own connections
	rebeanstalk()

	while True:

		logger.info( "==============================")
		logger.info( "processed %d samples so far" % count.value)
		try:
			#not great, but the parent is the only consumer of r items
			thing = r.get(block=False)
			results.append(thing)
		except:
			logger.warning( "results queue exception")
		
		if len(results) > 0:
			logger.info( "average sample time: %s" % str(sum(results) / float(len(results))))
		try:
			if BSMSBOXQ not in beanstalk.tubes():
					logger.info( "there are no samples in the beanstalk")
			else:
				if beanstalk.peek_ready() is not None:
					logger.info( str(beanstalk.stats_tube(BSMSBOXQ)['current-jobs-ready']) + " samples ready to process")
				else:
					logger.info( "0 samples ready to process")
				if beanstalk.peek_reserved() is not None:
					logger.info( str(beanstalk.stats_tube(BSMSBOXQ)['current-jobs-reserved']) + " samples are processing")
				else:
					logger.info( "0 samples are processing")
				if beanstalk.peek_delayed() is not None:
					logger.info( str(beanstalk.stats_tube(BSMSBOXQ)['current-jobs-delayed']) + " samples are delayed")
				else:
					logger.info( "0 samples are delayed")
		except KeyError:
			logger.warning( "beanstalk keyerror")
		except:
			logger.warning( "beanstalk general error")
		logger.info( "about " + str(q.qsize()) + " current q items")
		logger.info( "adb has failed " + str(ADBFAILCOUNT.value) + " times since last kick")
		logger.debug( "should be " + str(NUMWORKERS) + " processes:")
		walive = 0
		wdead = 0
		for j in jobs:
			if j.is_alive():
				logger.debug( "   " + str(j.pid))
				walive += 1
			else: 
				logger.debug( "   dead")
				wdead += 1
				#this will kill the controller, leaving the children pipes wanting more (you will get sigpipe errors)
				#this is pretty harsh and shouldn't probably be done in production
				#TODO
				#sys.exit(1)
		logger.info( "%s alive; %s dead" % (walive, wdead))
		updateStatus(NUMWORKERS,walive,wdead)

		list_VMs(VMs)
		time.sleep(VM_POLL_REST + 10)

		#blocks until all items in q are processed
		#safe to exit
		#should check for sigint
		#if q.qsize() == 0:
		#	for i in jobs:
		#		q.put("die")
		#	q.close()

	sys.exit(0)


	signal.signal(signal.SIGINT, sigint_handler)
	syslog.syslog('Startup - Entering main polling loop...')
	while True:

		get_VMs(VMs)
		list_VMs(VMs)
		#make sure any pcaps are killed and we are starting with a clean filesystem
		#pcap_terminate(m)
		#job_cleanup(m)

		#check for a job in the beanstalk Q
		if not beanstalk:
			error_log('Re-establishing connection to beanstalkd')
			beanstalk = beanstalkc.Connection(host=BSHOST, port=BSPORT)
			beanstalk.watch(BSMSBOXQ)
			beanstalk.use(BSMSBOXQ)
			beanstalk.ignore('default')

		#we want to reserve, not peak_ready because if we can't process, we want to release with a delay later
		beanstalkjob = beanstalk.reserve()

		#if there was a job and we got it then queue up analysis
		if beanstalkjob:
			try:
				job = eval(beanstalkjob.body)
			except:
				error_log('ERROR: could not eval job - invalid job')
				beanstalkjob.delete()
				return False

			#is there a VM compatible with this sample that is ready to be used?
			m = findCompatibleVM(job,VMs,vml)
			if m is not None:
				logger.info( "yay using VM " + str(m))
				#process sample

				sys.exit(0)

				#delete from queue if successfull
				#beanstalkjob.delete()
			else:
				#no VM found, put it back in the queue (nobody will process for 60 seconds
				beanstalkjob.release(delay=60)
				logger.info( "requeuing job requiring a target version " + job['target'])


#		
#		#break ot of the loop and exit if the assignments are clear and the terminate flag is set
		if flagTerminate and len(assignments)==0:
			syslog.syslog('All assigned jobs are completed (EXITING)...')
			break
		#put a pause in the polling cycle...set to 0 for no pause
		time.sleep(VM_POLL_REST)
		sys.exit(0)
	syslog.syslog('Shutdown - Leaving main polling loop...')
	return 0
dataset/ETHPy150Open tvidas/a5/scripts/bin/control.py/main/original