Beispiel #1
0
ISC_TASKFUNC_SCOPE isc_result_t
isc__task_beginexclusive(isc_task_t *task0) {
#ifdef USE_WORKER_THREADS
	isc__task_t *task = (isc__task_t *)task0;
	isc__taskmgr_t *manager = task->manager;
	REQUIRE(task->state == task_state_running);
	LOCK(&manager->lock);
	if (manager->exclusive_requested) {
		UNLOCK(&manager->lock);
		return (ISC_R_LOCKBUSY);
	}
	manager->exclusive_requested = ISC_TRUE;
	while (manager->tasks_running > 1) {
		WAIT(&manager->exclusive_granted, &manager->lock);
	}
	UNLOCK(&manager->lock);
#else
	UNUSED(task0);
#endif
	return (ISC_R_SUCCESS);
}
Beispiel #2
0
int main(){
	/*===Start===*/
	servo_setup();
	printf("Press any button to start");
	WAIT(a_button()||b_button()||c_button());
	//printf("waiting 2 seconds"); sleep(2);
	
	/*===Gold One===*/
	servo_drive_pos();
	squareup(-80,1);
	forward(35,100);
	squareup(80,1);
	get_gold();
	
	/*===Score Gold===*/
	back(17,80);
	score_gold();
	
	/*===Reposition===*/
	left(90,0,100);
	squareup(80,3);
	
	/*===Botguy===*/
	thread going=thread_create(arms_down_slow);
	thread_start(going);
	back(20,100);
	
	back(30,100);
	/*set_servo_position(ARM,ARM_UP);
	msleep(500);
	forward(34+5,100);
	back(5);
	set_servo_position(ARM,ARM_DOWN);
	msleep(500);*/
	
	/*===Tail===*/
	disable_servos();
	ao();
	
}
Beispiel #3
0
static isc_threadresult_t
#ifdef _WIN32			/* XXXDCL */
WINAPI
#endif
run(void *uap) {
	isc_timermgr_t *manager = uap;
	isc_time_t now;
	isc_result_t result;

	LOCK(&manager->lock);
	while (!manager->done) {
		TIME_NOW(&now);

		XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
					  ISC_MSG_RUNNING,
					  "running"), now);

		dispatch(manager, &now);

		if (manager->nscheduled > 0) {
			XTRACETIME2(isc_msgcat_get(isc_msgcat,
						   ISC_MSGSET_GENERAL,
						   ISC_MSG_WAITUNTIL,
						   "waituntil"),
				    manager->due, now);
			result = WAITUNTIL(&manager->wakeup, &manager->lock, &manager->due);
			INSIST(result == ISC_R_SUCCESS ||
			       result == ISC_R_TIMEDOUT);
		} else {
			XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						  ISC_MSG_WAIT, "wait"), now);
			WAIT(&manager->wakeup, &manager->lock);
		}
		XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
				      ISC_MSG_WAKEUP, "wakeup"));
	}
	UNLOCK(&manager->lock);

	return ((isc_threadresult_t)0);
}
bool process_skinchanger_detail_menu()
{
	if (!skinchanger_used)
	{
		set_status_text("Please apply a skin first");
		return false;
	}

	DWORD waitTime = 150;
	int foundTextures = 0;
	std::vector<std::string> menuCaptions;
	std::vector<int> menuValues;

	DWORD model = GAMEPLAY::GET_HASH_KEY((char *)chosenSkinName.c_str());
	if (STREAMING::IS_MODEL_IN_CDIMAGE(model) && STREAMING::IS_MODEL_VALID(model))
	{
		STREAMING::REQUEST_MODEL(model);
		while (!STREAMING::HAS_MODEL_LOADED(model))	WAIT(0);

		for (int i = 0; i < 15; i++)
		{
			for (int j = 0; j < 1000; j++)
			{
				int drawable = rand() % 10;
				int texture = rand() % 10;
				if (PED::IS_PED_COMPONENT_VARIATION_VALID(PLAYER::PLAYER_PED_ID(), i, drawable, texture))
				{
					std::string itemText = getSkinDetailAttribDescription(i);
					menuCaptions.push_back(itemText);
					menuValues.push_back(i);
					break;
				}
			}
		}

		STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model);
	}

	return drawGenericMenu<int>(menuCaptions, menuValues, skinDetailMenuIndex, "Skin Details", onconfirm_skinchanger_detail_menu, onhighlight_skinchanger_detail_menu, NULL);
}
Beispiel #5
0
bool pan_connect() {
    int error;

    if (!pan_enable()) {
        return false;
    }

    CALL_AND_WAIT(error = pan_interface->connect(&bt_remote_bdaddr, local_role, remote_role), pan_connection_state_changed);
    TASSERT(error == BT_STATUS_SUCCESS, "Error connecting to remote host: %d", error);
    TASSERT(pan_get_error() == BT_STATUS_SUCCESS, "Error connecting to BT device: %d", pan_get_error());
    TASSERT(pan_get_connection_state() == BTPAN_STATE_CONNECTING, "Invalid PAN state after connect: %d", pan_get_connection_state());
    TASSERT(pan_get_local_role() == local_role, "Incorrect local role: %d", pan_get_local_role());
    TASSERT(pan_get_remote_role() == remote_role, "Incorrect remote role: %d", pan_get_remote_role());

    WAIT(pan_connection_state_changed);
    TASSERT(pan_get_error() == BT_STATUS_SUCCESS, "Error connecting to BT device: %d", pan_get_error());
    TASSERT(pan_get_connection_state() == BTPAN_STATE_CONNECTED, "Invalid PAN state after connect: %d", pan_get_connection_state());
    TASSERT(pan_get_local_role() == local_role, "Incorrect local role: %d", pan_get_local_role());
    TASSERT(pan_get_remote_role() == remote_role, "Incorrect remote role: %d", pan_get_remote_role());

    return true;
}
Beispiel #6
0
boolean animate(char* data, int len) {
	for (int loop = 0; loop < 10; loop++) {
		for (int i = 0; i < len - 8; i++) {
			timenobtn = 0;
			//				setMatrix2(data + i);
			CLS(1);
			for (int k = 0; k < 8; k++)
				buf[k] = data[k + i];
			FLUSH();
			//				if (uart0_test())
			for (int j = 0; j < 90; j++) {
				WAIT(1);
				if (ux_btn()) {
					return 1;
				}
			}
		}
//		break;
	}
	deepPowerDown();
	return 1;
}
bool process_skinchanger_drawable_menu(std::string caption)
{
	DWORD waitTime = 150;
	int foundTextures = 0;
	std::vector<std::string> menuCaptions;
	std::vector<int> menuValues;

	DWORD model = GAMEPLAY::GET_HASH_KEY((char *)chosenSkinName.c_str());
	if (STREAMING::IS_MODEL_IN_CDIMAGE(model) && STREAMING::IS_MODEL_VALID(model))
	{
		STREAMING::REQUEST_MODEL(model);
		while (!STREAMING::HAS_MODEL_LOADED(model))	WAIT(0);

		for (int i = 0; i < 100; i++)
		{
			int drawable = i;
			for (int j = 0; j < 100; j++)
			{
				int texture = j;
				if (PED::IS_PED_COMPONENT_VARIATION_VALID(PLAYER::PLAYER_PED_ID(), skinDetailMenuValue, drawable, texture))
				{
					std::ostringstream ss;
					ss << "Drawable #" << std::to_string(drawable);

					menuCaptions.push_back(ss.str());
					menuValues.push_back(drawable);
					break;
				}
			}
		}

		STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model);
	}

	std::ostringstream ss;
	ss << caption << " Drawables";

	return drawGenericMenu<int>(menuCaptions, menuValues, skinDrawableMenuIndex, ss.str(), onconfirm_skinchanger_drawable_menu, onhighlight_skinchanger_drawable_menu, onexit_skinchanger_drawable_menu);
}
void onhighlight_skinchanger_drawable_menu(int selection, std::string caption, int value)
{
	//TODO: remove these two
	skinDrawableMenuIndex = selection;
	skinDrawableMenuValue = value;

	int texture;
	if (value == skinDrawableMenuValue && skinTextureMenuValue != -1)
	{
		texture = skinTextureMenuValue;
	}
	else
	{
		texture = findFirstValidPedTexture(value);
	}
	if (PED::IS_PED_COMPONENT_VARIATION_VALID(PLAYER::PLAYER_PED_ID(), skinDetailMenuValue, value, texture))
	{
		PED::SET_PED_COMPONENT_VARIATION(PLAYER::PLAYER_PED_ID(), skinDetailMenuValue, value, texture, 0);
	}
	skinchanger_used = true;
	WAIT(100);
}
Beispiel #9
0
/* Call only when writer mutex and buffer mutex are locked */
static bool_t wr_flush(Pipe_st *st)
{
    bool_t empty;

    do {
	empty = (st->wrp==st->rdp);
	if (!empty) {
	    if (!st->rd_open) {
		return False; /* Reader closed, not all data flushed */
	    }
	    /* The reader might be stalled; if it is, give it a kick */
	    if (st->waiting) {
		st->waiting=False;
		SIGNAL(&st->cv);
	    }
	    /* Now we wait to see what happens. */
	    st->waiting=True;
	    WAIT(&st->mu, &st->cv);
	}
    } while (!empty);
    return True;
}
KernelFile::KernelFile(char *fname, char mode, Entry entry, Drive *drive) {
	strcpy(this->fname, fname);
	this->mode = mode;
	this->entry = entry;
	this->drive = drive;

	cluster = new DataCluster(drive);

	switch (mode) {
		case 'r': pointer = 0;
			break;
		case 'w': pointer = 0;
			truncate();
			break;
		case 'a': pointer = entry.size;
			seek(pointer);
			break;
	}

	WAIT(numOfFilesMutex);
	drive->incNumOfFiles();
	SIGNAL(numOfFilesMutex);
}
/**
* Many props don't play nicely with PLACE_OBJECT_ON_GROUND_PROPERLY.
* Therefore we use one that is known to work properly to determine
* the height of the ground, and therefore the position for the other 
* prop, by spawning one and then deleting it.
*/
bool get_ground_height_at_position(Vector3 coords, float* result)
{
	Hash propHash = GAMEPLAY::GET_HASH_KEY("prop_veg_crop_03_cab");
	STREAMING::REQUEST_MODEL(propHash);
	DWORD now = GetTickCount();
	while (!STREAMING::HAS_MODEL_LOADED(propHash) && GetTickCount() < now + 5000)
	{
		make_periodic_feature_call();
		WAIT(0);
	}

	if (!STREAMING::HAS_MODEL_LOADED(propHash))
	{
		return false;
	}

	Vector3 minDimens;
	Vector3 maxDimens;
	GAMEPLAY::GET_MODEL_DIMENSIONS(propHash, &minDimens, &maxDimens);

	Object obj = OBJECT::CREATE_OBJECT_NO_OFFSET(propHash, coords.x, coords.y, coords.z, creationParam1, creationParam2, creationParam3);
	ENTITY::SET_ENTITY_VISIBLE(obj, false);
	OBJECT::PLACE_OBJECT_ON_GROUND_PROPERLY(obj);
	Vector3 objLocation = ENTITY::GET_ENTITY_COORDS(obj, 0);
	float objHeight = ENTITY::GET_ENTITY_HEIGHT(obj, objLocation.x, objLocation.y, objLocation.z, 1, 0);

	*result = objLocation.z - objHeight;
	if (minDimens.z < 0)
	{
		*result += minDimens.z;
	}

	OBJECT::DELETE_OBJECT(&obj);

	return true;
}
bool LoadScript( const char *script )
{
	if ( !IS_STRING_NULL(script) )
	{
		if ( DOES_SCRIPT_EXIST(script) )
		{
			if ( GET_NUMBER_OF_INSTANCES_OF_STREAMED_SCRIPT(script) > 0 )
			{
				TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME(script);
			}
			else
			{
				TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME(script);
				UNPAUSE_GAME();
				REQUEST_SCRIPT(script);
				while ( !HAS_SCRIPT_LOADED(script) ) WAIT(100);
				START_NEW_SCRIPT(script, 1024);
				MARK_SCRIPT_AS_NO_LONGER_NEEDED(script);
				return TRUE;
			}
		}
	}
	return FALSE;
}
void main()
{	
	set_periodic_feature_call(updateStuff);

	featurePlayerBlips = config->get_trainer_config()->setting_player_blips;
	featurePlayerHeadDisplay = config->get_trainer_config()->setting_player_head_display;
	featurePlayerBlipCone = config->get_trainer_config()->setting_player_blip_cone;
	featurePlayerNotifications = config->get_trainer_config()->setting_player_notifications;
	featureShowVoiceChatSpeaker = config->get_trainer_config()->setting_show_voice_chat_speaker;

	while (true)
	{
		if (is_menu_showing())
		{
			menu_beep(0);
			process_main_menu();
			set_menu_showing(false);
		}

		updateStuff();
		WAIT(0);
	}

}
/**
  * Pomeranje tekuce pozicije u fajlu
  */
char KernelFile::seek(BytesCnt bytesCnt) {
	if (getFileSize() == 0) return 0; // ako je prazan fajl
	if (bytesCnt > getFileSize()) return 0; // ako premasuje velicinu

	WAIT(partitionAccessMutex);

	pointer = bytesCnt;

	if ('r' != mode) cluster->writeToDisk();

	BytesCnt i = 0;
	ClusterNo clusterToFetch = entry.firstCluster;

	do {
		cluster->setClusterNo(clusterToFetch);
		cluster->readFromDisk();
		clusterToFetch = cluster->getNextCluster();
		i += EfficientClusterSize;
	} while (i < pointer);

	SIGNAL(partitionAccessMutex);

	return 1;
}
Beispiel #15
0
uchar twi_read(uchar W_ADDRESS)
{
  	uchar temp;
	START();	   			  	   //TWI启动
	WAIT();
    if (SATUS()!=_START) 
	return TRUE;      
    
    TWI_WRITE(W_MPU6050_ADDR); //写 MPU6050地址和写方式
    WAIT(); 
    if (SATUS()!=MT_SLA_ACK) 
	return TRUE;    
    
   	TWI_WRITE(W_ADDRESS);      //写 MPU6050相应寄存器地址
    WAIT();
    if (SATUS()!=MT_DATA_ACK) 
	return TRUE;
    
    START();            	       //TWI重新启动
    WAIT();
    if (SATUS()!=RE_START)  
	return TRUE;
    
    TWI_WRITE(R_MPU6050_ADDR); //写 MPU6050地址和读方式
    WAIT();
    if(SATUS()!=MR_SLA_ACK)  
	return TRUE;      
    
    TWI_READ();          	   //启动主TWI读方式
    WAIT();
    if(SATUS()!=MR_DATA_NOACK)//读完一个数停止接收数据 ,主机接收到不再接收应答信号 ,如果继续接收到应答信号
	return TRUE;			  //说明主机继续接收数据则为错误	 													 																		 
     
    
    temp=TWDR;        		   //读取 TWI接收数据
    STOP();         		   //TWI停止
    return temp;
}
/**
  * Upis na tekucu poziciju u fajl zadatog broja bajtova sa zadate memorijske adrese
  * TOOPT uzasno ruzna metoda
  */
char KernelFile::write(BytesCnt bytesCnt, char* buffer) {
	if ('r' == mode) return 0;
	if (0 == bytesCnt) return 0;

	WAIT(partitionAccessMutex);

	// TODO ukoliko vec nije dostugnuta maksimalna velicina fajla
	if (pointer + bytesCnt > entry.size) entry.size += bytesCnt;

	BytesCnt
		amount,
		bufferPointer = 0,
		localPointer = pointer % EfficientClusterSize;
	ClusterNo
		prevCluster = cluster->getPrevCluster(), 
		currentCluster = cluster->getClusterNo(),
		nextCluster = cluster->getNextCluster();

	if (0 == entry.firstCluster) { // fajl tek napravljen, postavi FirstCluster
		currentCluster = drive->getAndSetFreeClusterNo();
		entry.firstCluster = currentCluster;
		cluster->setClusterNo(currentCluster);
	}
	else if (0 == currentCluster) {
		currentCluster = entry.firstCluster;
		cluster->setClusterNo(currentCluster);
		
	}

	if (localPointer) { // ako trenutni klaster nije popunjen
		amount = EfficientClusterSize - localPointer;
		if (amount > bytesCnt) amount = bytesCnt;

		cluster->setRawData(buffer, localPointer, amount);

		bytesCnt -= amount;
		pointer += amount;
		bufferPointer += amount;
	}

	char toWr[EfficientClusterSize + 1]; //
	while (bytesCnt > 0) {

		localPointer = pointer % EfficientClusterSize;
		if (0 == localPointer && pointer > 0) {
			prevCluster = cluster->getClusterNo();
			currentCluster = cluster->getNextCluster();

			if (0 == currentCluster) { // ako ne postoji sledeci klaster, napravi ga i postavi
				currentCluster = drive->getAndSetFreeClusterNo();

				cluster->setNextCluster(currentCluster);
				cluster->writeToDisk();

				cluster->setClusterNo(currentCluster);
				cluster->setPrevCluster(prevCluster);
				cluster->setNextCluster(0);
			}
			else { // ako vec postoji sledeci klaster
				cluster->writeToDisk();

				cluster->setClusterNo(currentCluster);
				cluster->readFromDisk();
			}

			drive->getRootCluster()->updateEntry(entry); // TODEL ??? 
		}
		
		amount = EfficientClusterSize;
		if (amount > bytesCnt) amount = bytesCnt;

		cluster->setRawData(buffer + bufferPointer, localPointer, amount); // pozicija
		cluster->writeToDisk(amount); // upisi klaster na disk

		pointer += amount;
		bufferPointer += amount;
		bytesCnt -= amount;
	}

	SIGNAL(partitionAccessMutex);

	return 1;
}
Beispiel #17
0
int
pload (int tbl)
{
	int c = 0, i, status;
	
	if (verbose > 0)
	{
		fprintf (stderr, "Starting %d children to load %s",
			children, tdefs[tbl].comment);
	}
	for (c = 0; c < children; c++)
	{
		pids[c] = SPAWN ();
		if (pids[c] == -1)
		{
			perror ("Child loader not created");
			kill_load ();
			exit (-1);
		}
		else if (pids[c] == 0)	/* CHILD */
		{
			SET_HANDLER (stop_proc);
			verbose = 0;
			partial (tbl, c+1);
			exit (0);
		}
		else if (verbose > 0)			/* PARENT */
			fprintf (stderr, ".");
	}
	
	if (verbose > 0)
		fprintf (stderr, "waiting...");

	c = children;
	while (c)
	{
		i = WAIT (&status, pids[c - 1]);
		if (i == -1 && children)
		{
			if (errno == ECHILD)
				fprintf (stderr, "\nCould not wait on pid %d\n", pids[c - 1]);
			else if (errno == EINTR)
				fprintf (stderr, "\nProcess %d stopped abnormally\n", pids[c - 1]);
			else if (errno == EINVAL)
				fprintf (stderr, "\nProgram bug\n");
		}
		if (! WIFEXITED(status)) {
			(void) fprintf(stderr, "\nProcess %d: ", i);
			if (WIFSIGNALED(status)) {
				(void) fprintf(stderr, "rcvd signal %d\n",
					WTERMSIG(status));
				} else if (WIFSTOPPED(status)) {
				(void) fprintf(stderr, "stopped, signal %d\n",
					WSTOPSIG(status));
					}
				
			}
		c--;
	}

	if (verbose > 0)
		fprintf (stderr, "done\n");
	return (0);
}
void main(void)
{
	TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME("scriptmgr");
	ADD_ARMOUR_TO_CHAR(GetPlayerPed(), 100);
	CLEAR_ZONE(414.907, 28.0238, 8.79453, 200.0);
	SET_THIS_SCRIPT_CAN_REMOVE_BLIPS_CREATED_BY_ANY_SCRIPT(1);
	INIT_SETTINGS(420.828, 28.8978, 8.78683, 100.0);
	while ( ++num_items < MAX_PAGES ) selection_mem[num_items] = 0;
	while ( !IS_PLAYER_SCRIPT_CONTROL_ON(GetPlayerIndex()) ) WAIT(1000);
	
    while (TRUE)
    {
		WAIT(0);
		GET_CHAR_COORDINATES(GetPlayerPed(), &px, &py, &pz);
		GET_CHAR_HEADING(GetPlayerPed(), &ph);
		
		if(objrc == 0)
		{
			DRAW_MENU();
			PRINT_MAIN_LOGO(0.43, 0.05, "Lost MC RIP");
			PRINT_DESC(0.35, 0.11, "Recreation of GTA V Online mission \"Lost MC RIP\"");
			//PRINT_DESC(0.20, 0.13, "Test1");
			//PRINT_DESC(0.20, 0.15, "Test2");
		}
		
		if(objrc > objstart && objrc != objend)
		{
			PRINT_LIVES();
			POLICE(0, 0);
			MANAGE_PLAYER();
			MANAGE_ACTORS(14);
			ALTER_WANTED_LEVEL(GetPlayerIndex(), 0);	
		}
	
		if(objrc == 1)
		{
			UNLOCK_FRONTEND_DISPLAYS();
			APPLY_SELECTED_OPTIONS(level, weather, time);
			CLEAR_ZONE(480.671, 330.929, 8.57156, 50.0);
			SPAWN_VEHICLE(0, vehmodel,  BLIP_COLOR_WHITE, 414.907, 28.0238, 8.79453, 10.0, 25000, 0);
			SPAWN_VEHICLE(1, MODEL_HELLFURY, NOBLIP,  480.671, 330.929, 8.57156, 287.0, vhealth, 1);
			SPAWN_VEHICLE(2, MODEL_HELLFURY, NOBLIP,  500.989, 331.218, 8.57157, 287.0, vhealth, 1);
			SPAWN_VEHICLE(3, MODEL_HELLFURY, NOBLIP,  462.637, 342.84,  8.57144, 287.0, vhealth, 1);
			SPAWN_VEHICLE(4, MODEL_HELLFURY, NOBLIP,  456.194, 328.523, 8.57156, 287.0, vhealth, 1);
			SPAWN_VEHICLE(5, MODEL_ROMERO,   NOBLIP,  469.083, 341.918, 8.57143,   0.0, vhealth, 1);
			SPAWN_ACTOR(0,   MODEL_M_M_GBIK_LO_03, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 477.765, 330.598, 8.57155, 0.0, 0);
			SPAWN_ACTOR(1,   MODEL_M_Y_GBIK_HI_01, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 487.11,  332.822, 8.58402, 0.0, 0);
			SPAWN_ACTOR(2,   MODEL_M_Y_GBIK_HI_02, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 462.72,  329.053, 8.57155, 0.0, 0);
			SPAWN_ACTOR(3,   MODEL_M_Y_GBIK_LO_01, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 455.702, 331.683, 8.57326, 0.0, 0);
			SPAWN_ACTOR(4,   MODEL_M_Y_GBIK_LO_02, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 453.886, 342.619, 8.57142, 0.0, 0);
			SPAWN_ACTOR(5,   MODEL_M_M_GBIK_LO_03, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 455.879, 353.054, 8.57143, 0.0, 0);
			SPAWN_ACTOR(6,   MODEL_M_Y_GBIK_HI_01, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 461.334, 354.282, 8.55088, 0.0, 0);
			SPAWN_ACTOR(7,   MODEL_M_Y_GBIK_HI_02, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 452.701, 350.135, 8.57144, 0.0, 0);
			SPAWN_ACTOR(8,   MODEL_M_Y_GBIK_LO_01, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 475.867, 352.833, 8.57144, 0.0, 0);
			SPAWN_ACTOR(9,   MODEL_M_Y_GBIK_LO_02, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 485.464, 355.757, 8.57232, 0.0, 0);
			SPAWN_ACTOR(10,  MODEL_M_M_GBIK_LO_03, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 494.51,  355.139, 8.57158, 0.0, 0);
			SPAWN_ACTOR(11,  MODEL_M_Y_GBIK_HI_01, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 501.969, 343.139, 8.57158, 0.0, 0);
			SPAWN_ACTOR(12,  MODEL_M_Y_GBIK_HI_02, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 510.718, 339.741, 8.57158, 0.0, 0);
			SPAWN_ACTOR(13,  MODEL_M_Y_GBIK_LO_01, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 513.053, 328.065, 8.57157, 0.0, 0);
			SPAWN_ACTOR(14,  MODEL_M_Y_GBIK_LO_02, WEAPON_M4,  BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 505.737, 314.082, 8.57796, 0.0, 0);
			PLAY_CHECKPOINT_SOUND();
			objrc++;
		}
		
		if(objrc == 2)
		{
			PRINT_TXT("Take out the ~R~Lost~S~");
			
			if(peds[0].retc == 2 && peds[1].retc == 2 && peds[2].retc == 2 && peds[3].retc == 2 && peds[4].retc == 2 && peds[5].retc == 2 && peds[6].retc == 2 && peds[7].retc == 2 && peds[8].retc == 2 && peds[9].retc == 2 && peds[10].retc == 2 && peds[11].retc == 2 && peds[12].retc == 2 && peds[13].retc == 2 && peds[14].retc == 2)
			{
				objrc++;
			}	
		}
		
		if(objrc == 3)
		{
			MISSION_COMPLETE("", 13000);
		}
	}
}
Beispiel #19
0
/* TLS: making a conservative guess at which system calls need to be
   mutexed.  I'm doing it whenever I see the process table altered or
   affected, so this is the data structure that its protecting.

   At some point, the SET_FILEPTRs should be protected against other
   threads closing that stream.  Perhaps for such things a
   thread-specific stream table should be used.
*/
xsbBool sys_system(CTXTdeclc int callno)
{
  //  int pid;
  Integer pid;

  switch (callno) {
  case PLAIN_SYSTEM_CALL: /* dumb system call: no communication with XSB */
    /* this call is superseded by shell and isn't used */
    ctop_int(CTXTc 3, system(ptoc_string(CTXTc 2)));
    return TRUE;
  case SLEEP_FOR_SECS:
#ifdef WIN_NT
    Sleep((int)iso_ptoc_int_arg(CTXTc 2,"sleep/1",1) * 1000);
#else
    sleep(iso_ptoc_int_arg(CTXTc 2,"sleep/1",1));
#endif
    return TRUE;
  case GET_TMP_FILENAME:
    ctop_string(CTXTc 2,tempnam(NULL,NULL));
    return TRUE;
  case IS_PLAIN_FILE:
  case IS_DIRECTORY:
  case STAT_FILE_TIME:
  case STAT_FILE_SIZE:
    return file_stat(CTXTc callno, ptoc_longstring(CTXTc 2));
  case EXEC: {
#ifdef HAVE_EXECVP
    /* execs a new process in place of XSB */
    char *params[MAX_SUBPROC_PARAMS+2];
    prolog_term cmdspec_term;
    int index = 0;
    
    cmdspec_term = reg_term(CTXTc 2);
    if (islist(cmdspec_term)) {
      prolog_term temp, head;
      char *string_head=NULL;

      if (isnil(cmdspec_term))
	xsb_abort("[exec] Arg 1 must not be an empty list.");
      
      temp = cmdspec_term;
      do {
	head = p2p_car(temp);
	temp = p2p_cdr(temp);
	if (isstring(head)) 
	  string_head = string_val(head);
	else
	  xsb_abort("[exec] non-string argument passed in list.");
	
	params[index++] = string_head;
	if (index > MAX_SUBPROC_PARAMS)
	  xsb_abort("[exec] Too many arguments.");
      } while (!isnil(temp));
      params[index] = NULL;
    } else if (isstring(cmdspec_term)) {
      char *string = string_val(cmdspec_term);
      split_command_arguments(string, params, "exec");
    } else
      xsb_abort("[exec] 1st argument should be term or list of strings.");

    if (execvp(params[0], params)) 
      xsb_abort("[exec] Exec call failed.");
#else
    xsb_abort("[exec] builtin not supported in this architecture.");
#endif
  }
    
  case SHELL: /* smart system call: like SPAWN_PROCESS, but returns error code
		 instead of PID. Uses system() rather than execvp.
		 Advantage: can pass arbitrary shell command. */
  case SPAWN_PROCESS: { /* spawn new process, reroute stdin/out/err to XSB */
    /* +CallNo=2, +ProcAndArgsList,
       -StreamToProc, -StreamFromProc, -StreamFromProcStderr,
       -Pid */
    static int pipe_to_proc[2], pipe_from_proc[2], pipe_from_stderr[2];
    int toproc_stream=-1, fromproc_stream=-1, fromproc_stderr_stream=-1;
    int pid_or_status;
    FILE *toprocess_fptr=NULL,
      *fromprocess_fptr=NULL, *fromproc_stderr_fptr=NULL;
    char *params[MAX_SUBPROC_PARAMS+2]; /* one for progname--0th member,
				       one for NULL termination*/
    prolog_term cmdspec_term, cmdlist_temp_term;
    prolog_term cmd_or_arg_term;
    xsbBool toproc_needed=FALSE, fromproc_needed=FALSE, fromstderr_needed=FALSE;
    char *cmd_or_arg=NULL, *shell_cmd=NULL;
    int idx = 0, tbl_pos;
    char *callname=NULL;
    xsbBool params_are_in_a_list=FALSE;

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );

    init_process_table();

    if (callno == SPAWN_PROCESS)
      callname = "spawn_process/5";
    else
      callname = "shell/[1,2,5]";

    cmdspec_term = reg_term(CTXTc 2);
    if (islist(cmdspec_term))
      params_are_in_a_list = TRUE;
    else if (isstring(cmdspec_term))
      shell_cmd = string_val(cmdspec_term);
    else if (isref(cmdspec_term))
      xsb_instantiation_error(CTXTc callname,1);
    else    
      xsb_type_error(CTXTc "atom or list e.g. [command, arg, ...]",cmdspec_term,callname,1);
    
    // xsb_abort("[%s] Arg 1 must be an atom or a list [command, arg, ...]",
    // callname);

    /* the user can indicate that he doesn't want either of the streams created
       by putting an atom in the corresponding argument position */
    if (isref(reg_term(CTXTc 3)))
      toproc_needed = TRUE;
    if (isref(reg_term(CTXTc 4)))
      fromproc_needed = TRUE;
    if (isref(reg_term(CTXTc 5)))
      fromstderr_needed = TRUE;

    /* if any of the arg streams is already used by XSB, then don't create
       pipes --- use these streams instead. */
    if (isointeger(reg_term(CTXTc 3))) {
      SET_FILEPTR(toprocess_fptr, oint_val(reg_term(CTXTc 3)));
    }
    if (isointeger(reg_term(CTXTc 4))) {
      SET_FILEPTR(fromprocess_fptr, oint_val(reg_term(CTXTc 4)));
    }
    if (isointeger(reg_term(CTXTc 5))) {
      SET_FILEPTR(fromproc_stderr_fptr, oint_val(reg_term(CTXTc 5)));
    }

    if (!isref(reg_term(CTXTc 6)))
      xsb_type_error(CTXTc "variable (to return process id)",reg_term(CTXTc 6),callname,5);
    //      xsb_abort("[%s] Arg 5 (process id) must be a variable", callname);

    if (params_are_in_a_list) {
      /* fill in the params[] array */
      if (isnil(cmdspec_term))
	xsb_abort("[%s] Arg 1 must not be an empty list", callname);
      
      cmdlist_temp_term = cmdspec_term;
      do {
	cmd_or_arg_term = p2p_car(cmdlist_temp_term);
	cmdlist_temp_term = p2p_cdr(cmdlist_temp_term);
	if (isstring(cmd_or_arg_term)) {
	  cmd_or_arg = string_val(cmd_or_arg_term);
	}
	else 
	  xsb_abort("[%s] Non string list member in the Arg",
		    callname);
	
	params[idx++] = cmd_or_arg;
	if (idx > MAX_SUBPROC_PARAMS)
	  xsb_abort("[%s] Too many arguments passed to subprocess",
		    callname);
	
      } while (!isnil(cmdlist_temp_term));

      params[idx] = NULL; /* null termination */

    } else { /* params are in a string */
      if (callno == SPAWN_PROCESS)
	split_command_arguments(shell_cmd, params, callname);
      else {
	/* if callno==SHELL => call system() => don't split shell_cmd */
	params[0] = shell_cmd;
	params[1] = NULL;
      }
    }
    
    /* -1 means: no space left */
    if ((tbl_pos = get_free_process_cell()) < 0) {
      xsb_warn(CTXTc "Can't create subprocess because XSB process table is full");
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return FALSE;
    }

      /* params[0] is the progname */
    pid_or_status = xsb_spawn(CTXTc params[0], params, callno,
			      (toproc_needed ? pipe_to_proc : NULL),
			      (fromproc_needed ? pipe_from_proc : NULL),
			      (fromstderr_needed ? pipe_from_stderr : NULL),
			      toprocess_fptr, fromprocess_fptr,
			      fromproc_stderr_fptr);
      
    if (pid_or_status < 0) {
      xsb_warn(CTXTc "[%s] Subprocess creation failed, Error: %d, errno: %d, Cmd: %s", callname,pid_or_status,errno,params[0]);
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return FALSE;
    }

    if (toproc_needed) {
      toprocess_fptr = fdopen(pipe_to_proc[1], "w");
      toproc_stream =  xsb_intern_fileptr(CTXTc toprocess_fptr,callname,"pipe","w",CURRENT_CHARSET); 
      ctop_int(CTXTc 3, toproc_stream);
    }
    if (fromproc_needed) {
      fromprocess_fptr = fdopen(pipe_from_proc[0], "r");
      fromproc_stream =  xsb_intern_fileptr(CTXTc fromprocess_fptr,callname,"pipe","r",CURRENT_CHARSET); 
      ctop_int(CTXTc 4, fromproc_stream);
    }
    if (fromstderr_needed) {
      fromproc_stderr_fptr = fdopen(pipe_from_stderr[0], "r");
      fromproc_stderr_stream
	= xsb_intern_fileptr(CTXTc fromproc_stderr_fptr,callname,"pipe","r",CURRENT_CHARSET); 
      ctop_int(CTXTc 5, fromproc_stderr_stream);
    }
    ctop_int(CTXTc 6, pid_or_status);

    xsb_process_table.process[tbl_pos].pid = pid_or_status;
    xsb_process_table.process[tbl_pos].to_stream = toproc_stream;
    xsb_process_table.process[tbl_pos].from_stream = fromproc_stream;
    xsb_process_table.process[tbl_pos].stderr_stream = fromproc_stderr_stream;
    concat_array(CTXTc params, " ",
		 xsb_process_table.process[tbl_pos].cmdline,MAX_CMD_LEN);
    
    SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
    return TRUE;
  }

  case GET_PROCESS_TABLE: { /* sys_system(3, X). X is bound to the list
	       of the form [process(Pid,To,From,Stderr,Cmdline), ...] */
    int i;
    prolog_term table_term_tail, listHead;
    prolog_term table_term=reg_term(CTXTc 2);

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );
    init_process_table();

    if (!isref(table_term))
      xsb_abort("[GET_PROCESS_TABLE] Arg 1 must be a variable");

    table_term_tail = table_term;
    for (i=0; i<MAX_SUBPROC_NUMBER; i++) {
      if (!FREE_PROC_TABLE_CELL(xsb_process_table.process[i].pid)) {
	c2p_list(CTXTc table_term_tail); /* make it into a list */
	listHead = p2p_car(table_term_tail);

	c2p_functor(CTXTc "process", 5, listHead);
	c2p_int(CTXTc xsb_process_table.process[i].pid, p2p_arg(listHead,1));
	c2p_int(CTXTc xsb_process_table.process[i].to_stream, p2p_arg(listHead,2));
	c2p_int(CTXTc xsb_process_table.process[i].from_stream, p2p_arg(listHead,3));
	c2p_int(CTXTc xsb_process_table.process[i].stderr_stream,
		p2p_arg(listHead,4));
	c2p_string(CTXTc xsb_process_table.process[i].cmdline, p2p_arg(listHead,5));

	table_term_tail = p2p_cdr(table_term_tail);
      }
    }
    c2p_nil(CTXTc table_term_tail); /* bind tail to nil */
    SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
    return p2p_unify(CTXTc table_term, reg_term(CTXTc 2));
  }

  case PROCESS_STATUS: {
    prolog_term pid_term=reg_term(CTXTc 2), status_term=reg_term(CTXTc 3);

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );

    init_process_table();

    if (!(isointeger(pid_term)))
      xsb_abort("[PROCESS_STATUS] Arg 1 (process id) must be an integer");
    pid = (int)oint_val(pid_term);

    if (!isref(status_term))
      xsb_abort("[PROCESS_STATUS] Arg 2 (process status) must be a variable");
    
    switch (process_status(pid)) {
    case RUNNING:
      c2p_string(CTXTc "running", status_term);
      break;
    case STOPPED:
      c2p_string(CTXTc "stopped", status_term);
      break;
    case EXITED_NORMALLY:
      c2p_string(CTXTc "exited_normally", status_term);
      break;
    case EXITED_ABNORMALLY:
      c2p_string(CTXTc "exited_abnormally", status_term);
      break;
    case ABORTED:
      c2p_string(CTXTc "aborted", status_term);
      break;
    case INVALID:
      c2p_string(CTXTc "invalid", status_term);
      break;
    default:
      c2p_string(CTXTc "unknown", status_term);
    }
    SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
    return TRUE;
  }

  case PROCESS_CONTROL: {
    /* sys_system(PROCESS_CONTROL, +Pid, +Signal). Signal: wait, kill */
    int status;
    prolog_term pid_term=reg_term(CTXTc 2), signal_term=reg_term(CTXTc 3);

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );
    init_process_table();

    if (!(isointeger(pid_term)))
      xsb_abort("[PROCESS_CONTROL] Arg 1 (process id) must be an integer");
    pid = (int)oint_val(pid_term);

    if (isstring(signal_term) && strcmp(string_val(signal_term), "kill")==0) {
      if (KILL_FAILED(pid)) {
	SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
	return FALSE;
      }
#ifdef WIN_NT
      CloseHandle((HANDLE) pid);
#endif
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return TRUE;
    }
    if (isconstr(signal_term)
	&& strcmp(p2c_functor(signal_term),"wait") == 0
	&& p2c_arity(signal_term)==1) {
      int exit_status;

      if (WAIT(pid, status) < 0) {
	SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
	return FALSE;
      }

#ifdef WIN_NT
      exit_status = status;
#else
      if (WIFEXITED(status))
	exit_status = WEXITSTATUS(status);
      else
	exit_status = -1;
#endif

      p2p_unify(CTXTc p2p_arg(signal_term,1), makeint(exit_status));
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return TRUE;
    }

    xsb_warn(CTXTc "[PROCESS_CONTROL] Arg 2: Invalid signal specification. Must be `kill' or `wait(Var)'");
    return FALSE;
  }
   
  case LIST_DIRECTORY: {
    /* assume all type- and mode-checking is done in Prolog */
    prolog_term handle = reg_term(CTXTc 2); /* ref for handle */
    char *dir_name = ptoc_longstring(CTXTc 3); /* +directory name */
    prolog_term filename = reg_term(CTXTc 4); /* reference for name of file */
    
    if (is_var(handle)) 
      return xsb_find_first_file(CTXTc handle,dir_name,filename);
    else
      return xsb_find_next_file(CTXTc handle,dir_name,filename);
  }

  default:
    xsb_abort("[SYS_SYSTEM] Wrong call number (an XSB bug)");
  } /* end case */
  return TRUE;
}
Beispiel #20
0
enum PubNub_BH PubNub::_request_bh(PubNub_BASE_CLIENT &client, unsigned long t_start, int timeout)
{
	/* Finish the first line of the request. */
	client.print(" HTTP/1.1\r\n");
	/* Finish HTTP request. */
	client.print("Host: ");
	client.print(origin);
	client.print("\r\nUser-Agent: PubNub-Arduino/1.0\r\nConnection: close\r\n\r\n");

#define WAIT() do { \
	while (!client.available()) { \
		/* wait, just check for timeout */ \
		if (millis() - t_start > (unsigned long) timeout * 1000) { \
			DBGprintln("Timeout in bottom half"); \
			return PubNub_BH_TIMEOUT; \
		} \
		if (!client.connected()) { \
			/* Oops, connection interrupted. */ \
			DBGprintln("Connection reset in bottom half"); \
			return PubNub_BH_ERROR; \
		} \
	} \
} while (0)

	/* Read first line with HTTP code. */
	/* "HTTP/1.x " */
	do {
		WAIT();
	} while (client.read() != ' ');
	/* Now, first digit of HTTP code. */
	WAIT();
	char c = client.read();
	if (c != '2') {
		/* HTTP code that is NOT 2xx means trouble.
		 * kthxbai */
		DBGprint("Wrong HTTP status first digit ");
		DBGprint((int) c, DEC);
		DBGprintln(" in bottom half");
		return PubNub_BH_ERROR;
	}

	/* Now, we enter in a state machine that shall guide us through
	 * the remaining headers to the beginning of the body. */
	enum {
		RS_SKIPLINE, /* Skip the rest of this line. */
		RS_LOADLINE, /* Try loading the line in a buffer. */
	} request_state = RS_SKIPLINE; /* Skip the rest of status line first. */
	bool chunked = false;

	while (client.connected() || client.available()) {
		/* Let's hope there is no stray LF without CR. */
		if (request_state == RS_SKIPLINE) {
			do {
				WAIT();
			} while (client.read() != '\n');
			request_state = RS_LOADLINE;

		} else { /* request_state == RS_LOADLINE */
			/* line[] must be enough to hold
			 * Transfer-Encoding: chunked (or \r\n) */
			const static char PROGMEM chunked_str[] = "Transfer-Encoding: chunked\r\n";
			char line[sizeof(chunked_str)]; /* Not NUL-terminated! */
			int linelen = 0;
			char ch = 0;
			do {
				WAIT();
				ch = client.read();
				line[linelen++] = ch;
				if (linelen == strlen_P(chunked_str)
				    && !strncasecmp_P(line, chunked_str, linelen)) {
					/* Chunked encoding header. */
					chunked = true;
					break;
				}
			} while (ch != '\n' && linelen < sizeof(line));
			if (ch != '\n') {
				/* We are not at the end of the line yet.
				 * Skip the rest of the line. */
				request_state = RS_SKIPLINE;
			} else if (linelen == 2 && line[0] == '\r') {
				/* Empty line. This means headers end. */
				break;
			}
		}
	}

	if (chunked) {
		/* There is one extra line due to Transfer-encoding: chunked.
		 * Our minimalistic support means that we hope for just
		 * a single chunk, just skip the first line after header. */
		do {
			WAIT();
		} while (client.read() != '\n');
	}

	/* Body begins now. */
	return PubNub_BH_OK;
}
Beispiel #21
0
int VNCServer::Client::Run()
{
	Log(">VNCServer::Client::Run [this:%p]\n",this);

	//Lock
	LOCK(cl->updateMutex);

	//Set new modified region
	cl->modifiedRegion = sraRgnCreateRect(0,0,cl->screen->width,cl->screen->height);

	//Until ended
	while (!wait.IsCanceled())
	{
		Debug("-VNCServer::Client lopp [this:%p,state:%d,empty:%d]\n",this,cl->state,sraRgnEmpty(cl->requestedRegion));

		//If connected, always require a FB Update Request (otherwise can crash.)
		if (cl->state == rfbClientRec::RFB_NORMAL && !sraRgnEmpty(cl->requestedRegion))
		{
			//If reseted
			if (reset)
			{
				Log("-Reseting client\n");
				//Reset message
				char msg[] = {16};
				//Write it
				if (!Write(msg,sizeof(msg)))
					//WS closed
					break;
				//Clear reset flag
				reset = false;
			}
/*

			//If the scren has been resized
			if (cl->newFBSizePending)
			{
				//Free region
				sraRgnDestroy(cl->modifiedRegion);
				//Set new modified region
				cl->modifiedRegion = sraRgnCreateRect(0,0,cl->screen->width,cl->screen->height);
			}
*/
		

			//We need to update by default
			bool haveUpdate = true;

			/* Now, get the region we're going to update, and remove
			it from cl->modifiedRegion _before_ we send the update.
			That way, if anything that overlaps the region we're sending
			is updated, we'll be sure to do another update later. */
			sraRegion* updateRegion = sraRgnCreateRgn(cl->modifiedRegion);

			//Check if we didn't already have a pending update
			if  (!FB_UPDATE_PENDING(cl))
				//Check it is inside requested region
				haveUpdate = !sraRgnEmpty(cl->modifiedRegion);//sraRgnAnd(updateRegion,cl->requestedRegion);

			//IF we are freezed
			if (freeze)
				//Don't send any change
				sraRgnMakeEmpty(updateRegion);

			//Clean modified region
			sraRgnMakeEmpty(cl->modifiedRegion);

			//Unlock region
			UNLOCK(cl->updateMutex);

			Debug("-VNCServer::Client update [this:%p,update:%d,mod:%d,req:%d]\n",this,haveUpdate,sraRgnEmpty(cl->modifiedRegion),sraRgnEmpty(cl->requestedRegion));

			//If we have to update and not freezed
			if (haveUpdate)
			{
				Debug(">VNCServer::Client SendFramebufferUpdate [%p]\n",this);
				/* Now actually send the update. */
				rfbIncrClientRef(cl);
				//LOCK(cl->sendMutex);
				rfbSendFramebufferUpdate(cl, updateRegion);
				//UNLOCK(cl->sendMutex);
				rfbDecrClientRef(cl);
				Debug("<VNCServer::Client SendFramebufferUpdate [%p]\n",this);
			}

			//Destroy region
			sraRgnDestroy(updateRegion);

			//Lock again
			LOCK(cl->updateMutex);
		}

		//Check if we have been cancelled
		if (wait.IsCanceled())
			//Exit
			break;

		//Wait cond
		Debug("<VNCServer::Client going to sleep [this:%p]\n",this);
		WAIT(cl->updateCond,cl->updateMutex);
		Debug(">VNCServer::Client waked up from wait mutex[this:%p,isCanceled:%d]\n",this,wait.IsCanceled());
	}
	//Unlock
	UNLOCK(cl->updateMutex);

	Log("<VNCServer::Client::Run [this:%p]\n",this);

	//OK
	return 0;
}
Beispiel #22
0
int char_buffer::run_output_filter(int filter, int argc, char **argv)
{
  int pipedes[2];
  PID_T child_pid;
  int status;

  print_args(argc, argv);
  if (pipe(pipedes) < 0)
    sys_fatal("pipe");

#if MAY_FORK_CHILD_PROCESS
  // This is the UNIX process model.  To invoke our post-processor,
  // we must `fork' the current process.

  if ((child_pid = fork()) < 0)
    sys_fatal("fork");

  else if (child_pid == 0) {
    // This is the child process fork.  We redirect its `stdin' stream
    // to read data emerging from our pipe.  There is no point in saving,
    // since we won't be able to restore later!

    set_redirection(STDIN_FILENO, pipedes[0]);

    // The parent process will be writing this data, so we should release
    // the child's writeable handle on the pipe, since we have no use for it.

    if (close(pipedes[1]) < 0)
      sys_fatal("close");

    // The IMAGE_OUTPUT_FILTER needs special output redirection...

    if (filter == IMAGE_OUTPUT_FILTER) {
      // with BOTH `stdout' AND `stderr' diverted to files.

      set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM);
      set_redirection(STDERR_FILENO, REGION_OUTPUT_STREAM);
    }

    // Now we are ready to launch the output filter.

    execvp(argv[0], argv);

    // If we get to here then the `exec...' request for the output filter
    // failed.  Diagnose it and bail out.

    error("couldn't exec %1: %2", argv[0], strerror(errno), ((char *)0));
    fflush(stderr);	// just in case error() didn't
    exit(1);
  }

  else {
    // This is the parent process fork.  We will be writing data to the
    // filter pipeline, and the child will be reading it.  We have no further
    // use for our read handle on the pipe, and should close it.

    if (close(pipedes[0]) < 0)
      sys_fatal("close");

    // Now we redirect the `stdout' stream to the inlet end of the pipe,
    // and push out the appropiately formatted data to the filter.

    pipedes[1] = save_and_redirect(STDOUT_FILENO, pipedes[1]);
    emit_troff_output(DEVICE_FORMAT(filter));

    // After emitting all the data we close our connection to the inlet
    // end of the pipe so the child process will detect end of data.

    set_redirection(STDOUT_FILENO, pipedes[1]);

    // Finally, we must wait for the child process to complete.

    if (WAIT(&status, child_pid, _WAIT_CHILD) != child_pid)
      sys_fatal("wait");
  }

#elif MAY_SPAWN_ASYNCHRONOUS_CHILD

  // We do not have `fork', (or we prefer not to use it),
  // but asynchronous processes are allowed, passing data through pipes.
  // This should be ok for most Win32 systems and is preferred to `fork'
  // for starting child processes under Cygwin.

  // Before we start the post-processor we bind its inherited `stdin'
  // stream to the readable end of our pipe, saving our own `stdin' stream
  // in `pipedes[0]'.

  pipedes[0] = save_and_redirect(STDIN_FILENO, pipedes[0]);

  // for the Win32 model,
  // we need special provision for saving BOTH `stdout' and `stderr'.

  int saved_stdout = dup(STDOUT_FILENO);
  int saved_stderr = STDERR_FILENO;

  // The IMAGE_OUTPUT_FILTER needs special output redirection...

  if (filter == IMAGE_OUTPUT_FILTER) {
    // with BOTH `stdout' AND `stderr' diverted to files while saving a
    // duplicate handle for `stderr'.

    set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM);
    saved_stderr = save_and_redirect(STDERR_FILENO, REGION_OUTPUT_STREAM);
  }

  // We then use an asynchronous spawn request to start the post-processor.

  if ((child_pid = spawnvp(_P_NOWAIT, argv[0], argv)) < 0) {
    // Should the spawn request fail we issue a diagnostic and bail out.

    error("cannot spawn %1: %2", argv[0], strerror(errno), ((char *)0));
    exit(1);
  }

  // Once the post-processor has been started we revert our `stdin'
  // to its original saved source, which also closes the readable handle
  // for the pipe.

  set_redirection(STDIN_FILENO, pipedes[0]);

  // if we redirected `stderr', for use by the image post-processor,
  // then we also need to reinstate its original assignment.

  if (filter == IMAGE_OUTPUT_FILTER)
    set_redirection(STDERR_FILENO, saved_stderr);

  // Now we redirect the `stdout' stream to the inlet end of the pipe,
  // and push out the appropiately formatted data to the filter.

  set_redirection(STDOUT_FILENO, pipedes[1]);
  emit_troff_output(DEVICE_FORMAT(filter));

  // After emitting all the data we close our connection to the inlet
  // end of the pipe so the child process will detect end of data.

  set_redirection(STDOUT_FILENO, saved_stdout);

  // And finally, we must wait for the child process to complete.

  if (WAIT(&status, child_pid, _WAIT_CHILD) != child_pid)
    sys_fatal("wait");

#else /* can't do asynchronous pipes! */

  // TODO: code to support an MS-DOS style process model
  //        should go here

#endif /* MAY_FORK_CHILD_PROCESS or MAY_SPAWN_ASYNCHRONOUS_CHILD */

  return 0;
}
Beispiel #23
0
static isc_result_t
doit(isc_rwlock_t *rwl, isc_rwlocktype_t type, isc_boolean_t nonblock) {
	isc_boolean_t skip = ISC_FALSE;
	isc_boolean_t done = ISC_FALSE;
	isc_result_t result = ISC_R_SUCCESS;

	REQUIRE(VALID_RWLOCK(rwl));

	LOCK(&rwl->lock);

#ifdef ISC_RWLOCK_TRACE
	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
				  ISC_MSG_PRELOCK, "prelock"), rwl, type);
#endif

	if (type == isc_rwlocktype_read) {
		if (rwl->readers_waiting != 0)
			skip = ISC_TRUE;
		while (!done) {
			if (!skip &&
			    ((rwl->active == 0 ||
			      (rwl->type == isc_rwlocktype_read &&
			       (rwl->writers_waiting == 0 ||
				rwl->granted < rwl->read_quota)))))
			{
				rwl->type = isc_rwlocktype_read;
				rwl->active++;
				rwl->granted++;
				done = ISC_TRUE;
			} else if (nonblock) {
				result = ISC_R_LOCKBUSY;
				done = ISC_TRUE;
			} else {
				skip = ISC_FALSE;
				rwl->readers_waiting++;
				WAIT(&rwl->readable, &rwl->lock);
				rwl->readers_waiting--;
			}
		}
	} else {
		if (rwl->writers_waiting != 0)
			skip = ISC_TRUE;
		while (!done) {
			if (!skip && rwl->active == 0) {
				rwl->type = isc_rwlocktype_write;
				rwl->active = 1;
				rwl->granted++;
				done = ISC_TRUE;
			} else if (nonblock) {
				result = ISC_R_LOCKBUSY;
				done = ISC_TRUE;
			} else {
				skip = ISC_FALSE;
				rwl->writers_waiting++;
				WAIT(&rwl->writeable, &rwl->lock);
				rwl->writers_waiting--;
			}
		}
	}

#ifdef ISC_RWLOCK_TRACE
	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
				  ISC_MSG_POSTLOCK, "postlock"), rwl, type);
#endif

	UNLOCK(&rwl->lock);

	return (result);
}
Beispiel #24
0
static error_t
open_hook (struct trivfs_peropen *po)
{
    error_t err = 0;
    int flags = po->openmodes;

    if (flags & (O_READ | O_WRITE))
    {
        mutex_lock (&active_fifo_lock);

        /* Wait until the active fifo has changed so that CONDITION is true.  */
#define WAIT(condition, noblock_err)					      \
  while (!err && !(condition))						      \
    {									      \
      if (flags & O_NONBLOCK)						      \
	{								      \
	  err = noblock_err;						      \
	  break;							      \
	}								      \
      else if (hurd_condition_wait (&active_fifo_changed, &active_fifo_lock)) \
	err = EINTR;							      \
    }

        if (flags & O_READ)
            /* When opening for read, what we do depends on what mode this server
               is running in.  The default (if ONE_READER is set) is to only
               allow one reader at a time, with additional opens for read
               blocking here until the old reader goes away; otherwise, we allow
               multiple readers.  If WAIT_FOR_WRITER is true, then once we've
               created a fifo, we also block until someone opens it for writing;
               otherwise, the first read will block until someone writes
               something.  */
        {
            if (one_reader)
                /* Wait until there isn't any active fifo, so we can make one. */
                WAIT (!active_fifo || !active_fifo->readers, EWOULDBLOCK);

            if (!err && active_fifo == NULL)
                /* No other readers, and indeed, no fifo; make one.  */
            {
                err = pipe_create (fifo_pipe_class, &active_fifo);
                if (! err)
                    active_fifo->flags &= ~PIPE_BROKEN; /* Avoid immediate EOF. */
            }
            if (!err)
            {
                pipe_add_reader (active_fifo);
                condition_broadcast (&active_fifo_changed);
                /* We'll unlock ACTIVE_FIFO_LOCK below; the writer code won't
                make us block because we've ensured that there's a reader
                 for it.  */

                if (wait_for_writer)
                    /* Wait until there's a writer.  */
                {
                    WAIT (active_fifo->writers, 0);
                    if (err)
                        /* Back out the new pipe creation.  */
                    {
                        pipe_remove_reader (active_fifo);
                        active_fifo = NULL;
                        condition_broadcast (&active_fifo_changed);
                    }
                }
            }
        }

        if (!err && (flags & O_WRITE))
            /* Open the active_fifo for writing.  If WAIT_FOR_READER is true,
               then we block until there's someone to read what we wrote,
               otherwise, if there's no fifo, we create one, which we just write
               into and leave it for someone to read later.  */
        {
            if (wait_for_reader)
                /* Wait until there's a fifo to write to.  */
                WAIT (active_fifo && active_fifo->readers, ENXIO);
            if (!err && active_fifo == NULL)
                /* No other readers, and indeed, no fifo; make one.  */
            {
                err = pipe_create (fifo_pipe_class, &active_fifo);
                if (!err)
                    active_fifo->flags &= ~PIPE_BROKEN;
            }
            if (!err)
            {
                pipe_add_writer (active_fifo);
                condition_broadcast (&active_fifo_changed);
            }
        }

        po->hook = active_fifo;

        mutex_unlock (&active_fifo_lock);
    }

    return err;
}
Beispiel #25
0
static void *
clientOutput(void *data)
{
    rfbClientPtr cl = (rfbClientPtr)data;
    rfbBool haveUpdate;
    sraRegion* updateRegion;

    while (1) {
        haveUpdate = false;
        while (!haveUpdate) {
		if (cl->sock == -1) {
			/* Client has disconnected. */
			return NULL;
		}
		if (cl->state != RFB_NORMAL || cl->onHold) {
			/* just sleep until things get normal */
			usleep(cl->screen->deferUpdateTime * 1000);
			continue;
		}

		LOCK(cl->updateMutex);

		if (sraRgnEmpty(cl->requestedRegion)) {
			; /* always require a FB Update Request (otherwise can crash.) */
		} else {
			haveUpdate = FB_UPDATE_PENDING(cl);
			if(!haveUpdate) {
				updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
				haveUpdate   = sraRgnAnd(updateRegion,cl->requestedRegion);
				sraRgnDestroy(updateRegion);
			}
		}

		if (!haveUpdate) {
			WAIT(cl->updateCond, cl->updateMutex);
		}

		UNLOCK(cl->updateMutex);
        }
        
        /* OK, now, to save bandwidth, wait a little while for more
           updates to come along. */
        usleep(cl->screen->deferUpdateTime * 1000);

        /* Now, get the region we're going to update, and remove
           it from cl->modifiedRegion _before_ we send the update.
           That way, if anything that overlaps the region we're sending
           is updated, we'll be sure to do another update later. */
        LOCK(cl->updateMutex);
	updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
        UNLOCK(cl->updateMutex);

        /* Now actually send the update. */
	rfbIncrClientRef(cl);
        LOCK(cl->sendMutex);
        rfbSendFramebufferUpdate(cl, updateRegion);
        UNLOCK(cl->sendMutex);
	rfbDecrClientRef(cl);

	sraRgnDestroy(updateRegion);
    }

    /* Not reached. */
    return NULL;
}
void do_spawn_model(Hash propHash, char* model, std::string title, bool silent)
{
	STREAMING::REQUEST_MODEL(propHash);
	DWORD now = GetTickCount();
	while (!STREAMING::HAS_MODEL_LOADED(propHash) && GetTickCount() < now + 5000 )
	{
		make_periodic_feature_call();
		WAIT(0);
	}

	if (!STREAMING::HAS_MODEL_LOADED(propHash))
	{
		std::ostringstream ss2;
		ss2 << "TIMEOUT: " << model;
		write_text_to_log_file(ss2.str());
		return;
	}

	Ped playerPed = PLAYER::PLAYER_PED_ID();
	FLOAT look = ENTITY::GET_ENTITY_HEADING(playerPed);
	FLOAT lookAni = look + 180.00;
	FLOAT lookOff = look + 90.00;
	FLOAT vecX = 0;
	FLOAT vecY = 0;
	BOOL getPosParam1 = 1;
	BOOL getPosParam2 = 1;
	BOOL getPosParam3 = 1;

	FLOAT spawnOffX = 0.0f;
	FLOAT spawnOffY = 3.5f;
	FLOAT spawnOffZ = 0.0f;

	Vector3 minDimens;
	Vector3 maxDimens;
	GAMEPLAY::GET_MODEL_DIMENSIONS(propHash, &minDimens, &maxDimens);
	spawnOffY = max(3.5f, 1.3f * max(maxDimens.x-minDimens.x, maxDimens.y-minDimens.y));
	spawnOffZ = 0.0f;

	Vector3 coords = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(playerPed, spawnOffX, spawnOffY, spawnOffZ);

	float objZBase = 0;
	bool translatable = get_ground_height_at_position(coords, &objZBase);

	Object obj = OBJECT::CREATE_OBJECT_NO_OFFSET(propHash, coords.x, coords.y, coords.z, creationParam1, creationParam2, creationParam3);
	ENTITY::SET_ENTITY_VELOCITY(obj, 0.0f, 0.0f, 0.0f);
	ENTITY::SET_ENTITY_ROTATION(obj, 0, 0, 0, 0, false);

	if (ENTITY::DOES_ENTITY_EXIST(obj))
	{
		ENTITY::SET_ENTITY_COLLISION(obj, 1, 0);
		
		//place on the ground doesn't work on half the items, so do it ourselves
		Vector3 curLocation = ENTITY::GET_ENTITY_COORDS(obj, 0);
		if (translatable)
		{
			if (minDimens.z < 0)
			{
				objZBase -= minDimens.z;
			}
			ENTITY::SET_ENTITY_COORDS_NO_OFFSET(obj, curLocation.x, curLocation.y, objZBase, 1, 1, 1);
		}
		else
		{
			//best effort in case of failure
			OBJECT::PLACE_OBJECT_ON_GROUND_PROPERLY(obj);
		}

		ENTITY::SET_ENTITY_HAS_GRAVITY(obj, propCreationHasGravity);

		if (propCreationIsInvincible)
		{
			ENTITY::SET_ENTITY_INVINCIBLE(obj, TRUE);
			ENTITY::SET_ENTITY_PROOFS(obj, 1, 1, 1, 1, 1, 1, 1, 1);
			ENTITY::SET_ENTITY_CAN_BE_DAMAGED(obj, FALSE);
		}
		ENTITY::FREEZE_ENTITY_POSITION(obj, propCreationIsImmovable);

		if (!propCreationIsImmovable)
		{
			//this unfreezes it
			ENTITY::APPLY_FORCE_TO_ENTITY(obj, 3, 0, 0, 0.1, 0, 0, 0, 0, 1, 1, 0, 0, 1);
			OBJECT::SET_ACTIVATE_OBJECT_PHYSICS_AS_SOON_AS_IT_IS_UNFROZEN(obj, TRUE);
		}

		ENTITY::SET_ENTITY_LOAD_COLLISION_FLAG(obj, true);

		if (propCreationIsOnFire)
		{
			FIRE::START_ENTITY_FIRE(obj);
		}

		ENTITY::SET_ENTITY_ALPHA(obj, ALPHA_VALUES[propCreationAlphaIndex], false);

		SpawnedPropInstance* record = new SpawnedPropInstance();
		record->instance = obj;

		record->title = title;
		record->counter = find_highest_instance_num_of_prop(propHash) + 1;
		record->isInvincible = propCreationIsInvincible;
		record->isImmovable = propCreationIsImmovable;
		record->hasGravity = propCreationHasGravity;

		propsWeCreated.push_back(record);
		manage_prop_set();
	}
	else
	{
		if (!silent)
		{
			std::ostringstream ss;
			ss << "Failed to create " << title;
			set_status_text(ss.str());
		}

		std::ostringstream ss2;
		ss2 << "INVALID-PROP: " << model;
		write_text_to_log_file(ss2.str());
		return;
	}

	if (!silent)
	{
		std::ostringstream ss;
		ss << "Spawned " << title;
		set_status_text(ss.str());
	}

	STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(propHash);
	//ENTITY::SET_OBJECT_AS_NO_LONGER_NEEDED(&obj);
}
Beispiel #27
0
/***
 *** Task Manager.
 ***/
static void
dispatch(isc_taskmgr_t *manager) {
	isc_task_t *task;
#ifndef ISC_PLATFORM_USETHREADS
	unsigned int total_dispatch_count = 0;
	isc_tasklist_t ready_tasks;
#endif /* ISC_PLATFORM_USETHREADS */

	REQUIRE(VALID_MANAGER(manager));

	/*
	 * Again we're trying to hold the lock for as short a time as possible
	 * and to do as little locking and unlocking as possible.
	 *
	 * In both while loops, the appropriate lock must be held before the
	 * while body starts.  Code which acquired the lock at the top of
	 * the loop would be more readable, but would result in a lot of
	 * extra locking.  Compare:
	 *
	 * Straightforward:
	 *
	 *	LOCK();
	 *	...
	 *	UNLOCK();
	 *	while (expression) {
	 *		LOCK();
	 *		...
	 *		UNLOCK();
	 *
	 *	       	Unlocked part here...
	 *
	 *		LOCK();
	 *		...
	 *		UNLOCK();
	 *	}
	 *
	 * Note how if the loop continues we unlock and then immediately lock.
	 * For N iterations of the loop, this code does 2N+1 locks and 2N+1
	 * unlocks.  Also note that the lock is not held when the while
	 * condition is tested, which may or may not be important, depending
	 * on the expression.
	 *
	 * As written:
	 *
	 *	LOCK();
	 *	while (expression) {
	 *		...
	 *		UNLOCK();
	 *
	 *	       	Unlocked part here...
	 *
	 *		LOCK();
	 *		...
	 *	}
	 *	UNLOCK();
	 *
	 * For N iterations of the loop, this code does N+1 locks and N+1
	 * unlocks.  The while expression is always protected by the lock.
	 */

#ifndef ISC_PLATFORM_USETHREADS
	ISC_LIST_INIT(ready_tasks);
#endif
	LOCK(&manager->lock);
	while (!FINISHED(manager)) {
#ifdef ISC_PLATFORM_USETHREADS
		/*
		 * For reasons similar to those given in the comment in
		 * isc_task_send() above, it is safe for us to dequeue
		 * the task while only holding the manager lock, and then
		 * change the task to running state while only holding the
		 * task lock.
		 */
		while ((EMPTY(manager->ready_tasks) ||
			manager->exclusive_requested) &&
			!FINISHED(manager))
		{
			XTHREADTRACE(isc_msgcat_get(isc_msgcat,
						    ISC_MSGSET_GENERAL,
						    ISC_MSG_WAIT, "wait"));
			WAIT(&manager->work_available, &manager->lock);
			XTHREADTRACE(isc_msgcat_get(isc_msgcat,
						    ISC_MSGSET_TASK,
						    ISC_MSG_AWAKE, "awake"));
		}
#else /* ISC_PLATFORM_USETHREADS */
		if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM ||
		    EMPTY(manager->ready_tasks))
			break;
#endif /* ISC_PLATFORM_USETHREADS */
		XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
					    ISC_MSG_WORKING, "working"));

		task = HEAD(manager->ready_tasks);
		if (task != NULL) {
			unsigned int dispatch_count = 0;
			isc_boolean_t done = ISC_FALSE;
			isc_boolean_t requeue = ISC_FALSE;
			isc_boolean_t finished = ISC_FALSE;
			isc_event_t *event;

			INSIST(VALID_TASK(task));

			/*
			 * Note we only unlock the manager lock if we actually
			 * have a task to do.  We must reacquire the manager
			 * lock before exiting the 'if (task != NULL)' block.
			 */
			DEQUEUE(manager->ready_tasks, task, ready_link);
			manager->tasks_running++;
			UNLOCK(&manager->lock);

			LOCK(&task->lock);
			INSIST(task->state == task_state_ready);
			task->state = task_state_running;
			XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
					      ISC_MSG_RUNNING, "running"));
			isc_stdtime_get(&task->now);
			do {
				if (!EMPTY(task->events)) {
					event = HEAD(task->events);
					DEQUEUE(task->events, event, ev_link);

					/*
					 * Execute the event action.
					 */
					XTRACE(isc_msgcat_get(isc_msgcat,
							    ISC_MSGSET_TASK,
							    ISC_MSG_EXECUTE,
							    "execute action"));
					if (event->ev_action != NULL) {
						UNLOCK(&task->lock);
						(event->ev_action)(task,event);
						LOCK(&task->lock);
					}
					dispatch_count++;
#ifndef ISC_PLATFORM_USETHREADS
					total_dispatch_count++;
#endif /* ISC_PLATFORM_USETHREADS */
				}

				if (task->references == 0 &&
				    EMPTY(task->events) &&
				    !TASK_SHUTTINGDOWN(task)) {
					isc_boolean_t was_idle;

					/*
					 * There are no references and no
					 * pending events for this task,
					 * which means it will not become
					 * runnable again via an external
					 * action (such as sending an event
					 * or detaching).
					 *
					 * We initiate shutdown to prevent
					 * it from becoming a zombie.
					 *
					 * We do this here instead of in
					 * the "if EMPTY(task->events)" block
					 * below because:
					 *
					 *	If we post no shutdown events,
					 *	we want the task to finish.
					 *
					 *	If we did post shutdown events,
					 *	will still want the task's
					 *	quantum to be applied.
					 */
					was_idle = task_shutdown(task);
					INSIST(!was_idle);
				}

				if (EMPTY(task->events)) {
					/*
					 * Nothing else to do for this task
					 * right now.
					 */
					XTRACE(isc_msgcat_get(isc_msgcat,
							      ISC_MSGSET_TASK,
							      ISC_MSG_EMPTY,
							      "empty"));
					if (task->references == 0 &&
					    TASK_SHUTTINGDOWN(task)) {
						/*
						 * The task is done.
						 */
						XTRACE(isc_msgcat_get(
							       isc_msgcat,
							       ISC_MSGSET_TASK,
							       ISC_MSG_DONE,
							       "done"));
						finished = ISC_TRUE;
						task->state = task_state_done;
					} else
						task->state = task_state_idle;
					done = ISC_TRUE;
				} else if (dispatch_count >= task->quantum) {
					/*
					 * Our quantum has expired, but
					 * there is more work to be done.
					 * We'll requeue it to the ready
					 * queue later.
					 *
					 * We don't check quantum until
					 * dispatching at least one event,
					 * so the minimum quantum is one.
					 */
					XTRACE(isc_msgcat_get(isc_msgcat,
							      ISC_MSGSET_TASK,
							      ISC_MSG_QUANTUM,
							      "quantum"));
					task->state = task_state_ready;
					requeue = ISC_TRUE;
					done = ISC_TRUE;
				}
			} while (!done);
			UNLOCK(&task->lock);

			if (finished)
				task_finished(task);

			LOCK(&manager->lock);
			manager->tasks_running--;
#ifdef ISC_PLATFORM_USETHREADS
			if (manager->exclusive_requested &&
			    manager->tasks_running == 1) {
				SIGNAL(&manager->exclusive_granted);
			}
#endif /* ISC_PLATFORM_USETHREADS */
			if (requeue) {
				/*
				 * We know we're awake, so we don't have
				 * to wakeup any sleeping threads if the
				 * ready queue is empty before we requeue.
				 *
				 * A possible optimization if the queue is
				 * empty is to 'goto' the 'if (task != NULL)'
				 * block, avoiding the ENQUEUE of the task
				 * and the subsequent immediate DEQUEUE
				 * (since it is the only executable task).
				 * We don't do this because then we'd be
				 * skipping the exit_requested check.  The
				 * cost of ENQUEUE is low anyway, especially
				 * when you consider that we'd have to do
				 * an extra EMPTY check to see if we could
				 * do the optimization.  If the ready queue
				 * were usually nonempty, the 'optimization'
				 * might even hurt rather than help.
				 */
#ifdef ISC_PLATFORM_USETHREADS
				ENQUEUE(manager->ready_tasks, task,
					ready_link);
#else
				ENQUEUE(ready_tasks, task, ready_link);
#endif
			}
		}
	}
#ifndef ISC_PLATFORM_USETHREADS
	ISC_LIST_APPENDLIST(manager->ready_tasks, ready_tasks, ready_link);
#endif
	UNLOCK(&manager->lock);
}
Beispiel #28
0
void main() {
	int keyLemmy = 0x4C;
	int keyHooker = 0x48;
	int keyBike = 0x42;
	int keySmoke = 0x4F;
	int keyDrink = 0x4B;
	int keyGuitar = 0x49;
	int keyShirt = 0x4A;
	int keyStop = 0x51;

	char iniPath[260];
	GetFullPathName("LemmyKilmister.ini", 261, iniPath, NULL);
	IniReader ini(iniPath);
	if (ini.fileExists()) {
		ini.readInt("Controls", "Lemmy", 0x4C, 16, keyLemmy);
		ini.readInt("Controls", "Hooker", 0x48, 16, keyHooker);
		ini.readInt("Controls", "Bike", 0x42, 16, keyBike);
		ini.readInt("Controls", "Smoke", 0x4F, 16, keySmoke);
		ini.readInt("Controls", "Drink", 0x4B, 16, keyDrink);
		ini.readInt("Controls", "Guitar", 0x49, 16, keyGuitar);
		ini.readInt("Controls", "Shirt", 0x4A, 16, keyShirt);
		ini.readInt("Controls", "Stop", 0x51, 16, keyStop);
	}

	Ped playerPed;
	Player playerID;
	Vector3 position;
	bool widescreen = GRAPHICS::GET_IS_WIDESCREEN();

	while (true) {
		// INIT
		playerID = PLAYER::PLAYER_ID();
		playerPed = PLAYER::PLAYER_PED_ID();
		position = ENTITY::GET_ENTITY_COORDS(playerPed, 1);

		// reset to normal skin if dies or get arrested
		Hash model = ENTITY::GET_ENTITY_MODEL(playerPed);
		if (ENTITY::IS_ENTITY_DEAD(playerPed) || PLAYER::IS_PLAYER_BEING_ARRESTED(playerID, TRUE)) {
			if (model != GAMEPLAY::GET_HASH_KEY("player_zero") &&
				model != GAMEPLAY::GET_HASH_KEY("player_one") &&
				model != GAMEPLAY::GET_HASH_KEY("player_two")) {
				WAIT(1000);
				model = GAMEPLAY::GET_HASH_KEY("player_zero");
				STREAMING::REQUEST_MODEL(model);
				while (!STREAMING::HAS_MODEL_LOADED(model))	WAIT(0);
				PLAYER::SET_PLAYER_MODEL(PLAYER::PLAYER_ID(), model);
				PED::SET_PED_DEFAULT_COMPONENT_VARIATION(PLAYER::PLAYER_PED_ID());
				STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model);
				while (ENTITY::IS_ENTITY_DEAD(PLAYER::PLAYER_PED_ID()) || PLAYER::IS_PLAYER_BEING_ARRESTED(playerID, TRUE))
					WAIT(0);
			}
		}

		// CHANGE SKIN
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keyLemmy)) {
			DWORD freemodeMale = GAMEPLAY::GET_HASH_KEY((char *)"mp_m_freemode_01");
			if (STREAMING::IS_MODEL_IN_CDIMAGE(freemodeMale) && STREAMING::IS_MODEL_VALID(freemodeMale)) {
				STREAMING::REQUEST_MODEL(freemodeMale);
				while (!STREAMING::HAS_MODEL_LOADED(freemodeMale))
					WAIT(0);
				PLAYER::SET_PLAYER_MODEL(PLAYER::PLAYER_ID(), freemodeMale);

				playerPed = PLAYER::PLAYER_PED_ID();
				PED::SET_PED_DEFAULT_COMPONENT_VARIATION(playerPed);

				// CLOTHES and FACE
				PED::SET_PED_HEAD_BLEND_DATA(playerPed, 0, 0, 0, 0, 0, 0, 1.0, 1.0, 1.0, true);
				PED::SET_PED_HEAD_OVERLAY(playerPed, 1, 27, 1.0); // bread
				PED::_0x497BF74A7B9CB952(playerPed, 1, 1, 0, 0); // beard color
				PED::SET_PED_HEAD_OVERLAY(playerPed, 2, 19, 1.0); // eyebrow
				PED::_0x497BF74A7B9CB952(playerPed, 2, 1, 0, 0); // eyebrow color
				PED::SET_PED_HEAD_OVERLAY(playerPed, 3, 14, 1.0); // ageing
				PED::SET_PED_HEAD_OVERLAY(playerPed, 10, 0, 1.0); // peli
				PED::_0x497BF74A7B9CB952(playerPed, 10, 1, 0, 0); // peli color
				
				PED::SET_PED_COMPONENT_VARIATION(playerPed, 2, 22, 0, 2); // hair
				PED::_0x4CFFC65454C93A49(playerPed, 0, 0); // hair color
				PED::SET_PED_COMPONENT_VARIATION(playerPed, 3, 11, 0, 2); // torso
				PED::SET_PED_COMPONENT_VARIATION(playerPed, 4, 4, 0, 2); // pants
				PED::SET_PED_COMPONENT_VARIATION(playerPed, 8, 15, 0, 2); // acc
				//PED::SET_PED_COMPONENT_VARIATION(playerPed, 6, 15, 0, 2); // shoes
				//PED::SET_PED_COMPONENT_VARIATION(playerPed, 11, 13, 2, 2); // t2
				PED::IS_PED_COMPONENT_VARIATION_VALID(playerPed, 6, 37, 0) ? PED::SET_PED_COMPONENT_VARIATION(playerPed, 6, 37, 0, 2) : PED::SET_PED_COMPONENT_VARIATION(playerPed, 6, 15, 0, 2);
				PED::IS_PED_COMPONENT_VARIATION_VALID(playerPed, 11, 95, 2) ? PED::SET_PED_COMPONENT_VARIATION(playerPed, 11, 95, 1, 2) : PED::SET_PED_COMPONENT_VARIATION(playerPed, 11, 13, 2, 2);

				// TATTOOS
				DWORD coll1 = GAMEPLAY::GET_HASH_KEY("multiplayer_overlays");
				DWORD tattoo1 = GAMEPLAY::GET_HASH_KEY("FM_Tat_Award_F_001");
				PED::_0x5F5D1665E352A839(playerPed, coll1, tattoo1);
				DWORD coll2 = GAMEPLAY::GET_HASH_KEY("multiplayer_overlays");
				DWORD tattoo2 = GAMEPLAY::GET_HASH_KEY("FM_Tat_M_038");
				PED::_0x5F5D1665E352A839(playerPed, coll2, tattoo2);

				// PROPS
				PED::SET_PED_PROP_INDEX(playerPed, 0, 13, 0, true); // hat
				PED::SET_PED_PROP_INDEX(playerPed, 1, 5, 0, true); // glasses

				STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(freemodeMale);
			}
		}

		// WEAR MOTORHEAD SHIRT
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keyShirt)) {
			PED::SET_PED_COMPONENT_VARIATION(PLAYER::PLAYER_PED_ID(), 3, 0, 0, 2); // torso
			PED::SET_PED_COMPONENT_VARIATION(PLAYER::PLAYER_PED_ID(), 11, 0, 2, 2); // t2
		}

		// SPAWN HEXER MOTORBIKE
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keyBike)) {
			// from Alexander Blade native trainer code
			DWORD model = GAMEPLAY::GET_HASH_KEY((char *)"HEXER");
			if (STREAMING::IS_MODEL_IN_CDIMAGE(model) && STREAMING::IS_MODEL_A_VEHICLE(model)) {
				STREAMING::REQUEST_MODEL(model);
				while (!STREAMING::HAS_MODEL_LOADED(model))
					WAIT(0);
				Vector3 coords = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(playerPed, 0.0, 5.0, 0.0);
				Vehicle veh = VEHICLE::CREATE_VEHICLE(model, coords.x, coords.y, coords.z, 0.0, 1, 1);
				VEHICLE::SET_VEHICLE_COLOURS(veh, 0, 0);
				VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(veh);

				WAIT(0);
				STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model);
				ENTITY::SET_VEHICLE_AS_NO_LONGER_NEEDED(&veh);
			}
		}

		// SPAWN HOOKERS
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keyHooker)) {
			DWORD hooker = GAMEPLAY::GET_HASH_KEY((char *)"s_f_y_hooker_01");
			if (STREAMING::IS_MODEL_IN_CDIMAGE(hooker) && STREAMING::IS_MODEL_VALID(hooker)) {
				STREAMING::REQUEST_MODEL(hooker);
				while (!STREAMING::HAS_MODEL_LOADED(hooker))
					WAIT(0);
				playerPed = PLAYER::PLAYER_PED_ID();
				Vector3 pos = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(playerPed, 0.0, 3.0, 0.0);
				Ped ped = PED::CREATE_PED(5, hooker, pos.x, pos.y, pos.z, 1, false, true);

				// the hooker is YOUR hooker
				int groupIndex = PED::GET_PED_GROUP_INDEX(playerPed);
				PED::SET_PED_AS_GROUP_LEADER(playerPed, groupIndex);
				PED::SET_PED_AS_GROUP_MEMBER(ped, groupIndex);
				PED::SET_PED_NEVER_LEAVES_GROUP(ped, true);

				WAIT(100);
				STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hooker);
			}
		}

		// ANIMATIONS
		// SMOKING
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keySmoke)) {
			playerPed = PLAYER::PLAYER_PED_ID();
			AI::TASK_START_SCENARIO_IN_PLACE(playerPed, "WORLD_HUMAN_SMOKING", 0, 1);
		}

		// DRINKING
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keyDrink)) {
			playerPed = PLAYER::PLAYER_PED_ID();
			AI::TASK_START_SCENARIO_IN_PLACE(playerPed, "WORLD_HUMAN_DRINKING", 0, 1);
		}

		// GUITAR
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keyGuitar)) {
			playerPed = PLAYER::PLAYER_PED_ID();
			AI::TASK_START_SCENARIO_IN_PLACE(playerPed, "WORLD_HUMAN_MUSICIAN", 0, 1);
		}

		// STOP ANIMATIONS
		if (IsKeyDown(VK_SHIFT) && IsKeyJustUp(keyStop)) {
			playerPed = PLAYER::PLAYER_PED_ID();
			AI::CLEAR_PED_TASKS_IMMEDIATELY(playerPed);
		}
		
		// DEBUGGING
		/*
		if (IsKeyDown(0x31)) {
			playerPed = PLAYER::PLAYER_PED_ID();
			int numVar = PED::GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(playerPed, 0);

			int face = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 0);
			int head = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 1);
			int hair = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 2);
			int tors = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 3);
			int leg = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 4);
			int hand = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 5);
			int feet = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 6);
			int eye = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 7);
			int acc = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 8);
			int task = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 9);
			int tex = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 10);
			int t2 = PED::GET_PED_DRAWABLE_VARIATION(playerPed, 11);

			int hat = PED::GET_PED_PROP_INDEX(playerPed, 0);
			int glasses = PED::GET_PED_PROP_INDEX(playerPed, 1);

			int ov0 = PED::_0xA60EF3B6461A4D43(playerPed, 0);
			int ov1 = PED::_0xA60EF3B6461A4D43(playerPed, 1);
			int ov2 = PED::_0xA60EF3B6461A4D43(playerPed, 2);
			int ov3 = PED::_0xA60EF3B6461A4D43(playerPed, 3);
			int ov4 = PED::_0xA60EF3B6461A4D43(playerPed, 4);
			int ov5 = PED::_0xA60EF3B6461A4D43(playerPed, 5);
			int ov6 = PED::_0xA60EF3B6461A4D43(playerPed, 6);
			int ov7 = PED::_0xA60EF3B6461A4D43(playerPed, 7);
			int ov8 = PED::_0xA60EF3B6461A4D43(playerPed, 8);
			int ov9 = PED::_0xA60EF3B6461A4D43(playerPed, 9);
			int ov10 = PED::_0xA60EF3B6461A4D43(playerPed, 10);
			int ov11 = PED::_0xA60EF3B6461A4D43(playerPed, 11);

			DWORD coll1 = GAMEPLAY::GET_HASH_KEY("mpchristmas2_overlays");
			DWORD tattoo1 = GAMEPLAY::GET_HASH_KEY("MP_Xmas2_M_Tat_000");
			int zone = PED::_0x9FD452BFBE7A7A8B(coll1, tattoo1);

			char text1[300], text2[300];
			sprintf_s(text1, "FAC:%d HED:%d HAIR:%d TOR:%d LEG:%d HAND:%d FEET:%d EYE:%d ACC:%d TASK:%d TEX:%d TORSO2:%d", face, head, hair, tors, leg, hand, feet, eye, acc, task, tex, t2);
			draw_text(text1, 0.5, 0, 0.3);
			sprintf_s(text1, "HAT:%d GLASSES:%d", hat, glasses);
			draw_text(text1, 0.6, 0, 0.3);
			sprintf_s(text2, "ov0:%d ov1:%d ov2:%d ov3:%d ov4:%d ov5:%d ov6:%d ov7:%d ov8:%d ov9:%d ov10:%d ov11:%d", ov0, ov1, ov2, ov3, ov4, ov5, ov6, ov7, ov8, ov9, ov10, ov11);
			draw_text(text2, 0.7, 0, 0.3);
		}
		*/

		WAIT(0);
	}
}
    void dll_top::fc_init(){
        LOG_DEBUG<<"DLL: fc_init begins...";
        try{
            RefPciePacket send_packet1; 
            RefPciePacket send_packet2; 
            RefPciePacket send_packet3; 
            RefPciePacket send_packet4; 
            RefPciePacket send_packet5; 
            RefPciePacket send_packet6; 
            sc_uint<8> data,dllp_byte1,dllp_byte2,dllp_byte3;	
            sc_uint<16> dllp_crc_mapped;
            sc_uint<64> tlu_ici_hw_reg,tlu_ecl_hw_reg;
            sc_uint<8>  nhc_reg,chc_reg,phc_reg;
            sc_uint<12> ndc_reg,cdc_reg,pdc_reg;

            /// Main Loop
            while ( true) 
            {
                /// Wait for core status register to be updated
                WAIT(csr_core_status_ev);
                csr_data_reg = csr_port.read_csr(PEU_CSR_A_CORE_STATUS_HW_ADDR);

                tlu_ici_hw_reg = csr_port.read_csr(PEU_CSR_A_TLU_ICI_HW_ADDR);

                nhc_reg=tlu_ici_hw_reg.range(39,32);
                chc_reg=tlu_ici_hw_reg.range(59,52);
                phc_reg=tlu_ici_hw_reg.range(19,12);
                ndc_reg=tlu_ici_hw_reg.range(31,20);
                cdc_reg=tlu_ici_hw_reg.range(51,40);
                pdc_reg=tlu_ici_hw_reg.range(11,0) ;

                if ( (csr_data_reg.range(48,44) == 16) & ~FC_INIT1_Complete )
                {
                    LOG_DEBUG << "_DLL_: Sending FCINIT1 DLLPS ";

                    wait(100,SC_NS);
                    //wait(700,SC_NS);

                    dllp_byte1.range(7,6)=0;
                    dllp_byte1.range(5,0)=phc_reg.range(7,2);

                    dllp_byte2.range(7,6)=phc_reg.range(1,0);
                    dllp_byte2.range(5,4)=0;
                    dllp_byte2.range(3,0)=pdc_reg.range(11,8);

                    dllp_byte3 = pdc_reg.range(7,0);

                    send_packet1 =  new pciePacket(6);
                    send_packet1->modify_byte(0,DLLP_INITFC1_P); // initfc1_p vc=0
                    send_packet1->modify_byte(1,dllp_byte1);
                    send_packet1->modify_byte(2,dllp_byte2);
                    send_packet1->modify_byte(3,dllp_byte3);

                    dllp_crc_mapped=calculate_dllp_crc(send_packet1,0,4);
                    send_packet1->modify_byte(4,dllp_crc_mapped.range(15,8));
                    send_packet1->modify_byte(5,dllp_crc_mapped.range(7,0));

                    send_packet1->set_control(SDP_CONTROL);

                    dll_pl_dllp_out.send_packet(send_packet1);
                    //send_packet1->dll2pl_display_sdp_packet(1);


                    wait(5,SC_NS);

                    dllp_byte1.range(7,6)=0;
                    dllp_byte1.range(5,0)=nhc_reg.range(7,2);

                    dllp_byte2.range(7,6)=nhc_reg.range(1,0);
                    dllp_byte2.range(5,4)=0;
                    dllp_byte2.range(3,0)=ndc_reg.range(11,8);

                    dllp_byte3 = ndc_reg.range(7,0);

                    send_packet2 =  new pciePacket(6);
                    send_packet2->modify_byte(0,DLLP_INITFC1_NP);
                    send_packet2->modify_byte(1,dllp_byte1);
                    send_packet2->modify_byte(2,dllp_byte2);
                    send_packet2->modify_byte(3,dllp_byte3);

                    dllp_crc_mapped=calculate_dllp_crc(send_packet2,0,4);
                    send_packet2->modify_byte(4,dllp_crc_mapped.range(15,8));
                    send_packet2->modify_byte(5,dllp_crc_mapped.range(7,0));
                    send_packet2->set_control(SDP_CONTROL);

                    dll_pl_dllp_out.send_packet(send_packet2);
                    //send_packet2->dll2pl_display_sdp_packet(1);

                    wait(5,SC_NS);

                    LOG_DEBUG << " FCINIT1: Sending InitFC1_Cpl " ;

                    send_packet3 =  new pciePacket(6);

                    dllp_byte1.range(7,6)=0;
                    dllp_byte1.range(5,0)=chc_reg.range(7,2);

                    dllp_byte2.range(7,6)=chc_reg.range(1,0);
                    dllp_byte2.range(5,4)=0;
                    dllp_byte2.range(3,0)=cdc_reg.range(11,8);

                    dllp_byte3 = cdc_reg.range(7,0);

                    send_packet3->modify_byte(0,DLLP_INITFC1_CPL);
                    send_packet3->modify_byte(1,dllp_byte1);
                    send_packet3->modify_byte(2,dllp_byte2);
                    send_packet3->modify_byte(3,dllp_byte3);

                    dllp_crc_mapped=calculate_dllp_crc(send_packet3,0,4);
                    send_packet3->modify_byte(4,dllp_crc_mapped.range(15,8));
                    send_packet3->modify_byte(5,dllp_crc_mapped.range(7,0));

                    send_packet3->set_control(SDP_CONTROL);

                    dll_pl_dllp_out.send_packet(send_packet3);
                    //send_packet3->dll2pl_display_sdp_packet(1);

                    wait(5,SC_NS);

                    FC_INIT1_Complete=1;
                }

                if ( (csr_data_reg.range(48,44) == 16) & ~FC_INIT2_Complete & FC_INIT1_Complete )
                {
                    LOG_DEBUG << "_DLL_: Sending FCINIT2 DLLPS " ;

                    dllp_byte1.range(7,6)=0;
                    dllp_byte1.range(5,0)=phc_reg.range(7,2);

                    dllp_byte2.range(7,6)=phc_reg.range(1,0);
                    dllp_byte2.range(5,4)=0;
                    dllp_byte2.range(3,0)=pdc_reg.range(11,8);

                    dllp_byte3 = pdc_reg.range(7,0);

                    send_packet4 =  new pciePacket(6);
                    send_packet4->modify_byte(0,DLLP_INITFC2_P);
                    send_packet4->modify_byte(1,dllp_byte1);
                    send_packet4->modify_byte(2,dllp_byte2);
                    send_packet4->modify_byte(3,dllp_byte3);

                    dllp_crc_mapped=calculate_dllp_crc(send_packet4,0,4);
                    send_packet4->modify_byte(4,dllp_crc_mapped.range(15,8));
                    send_packet4->modify_byte(5,dllp_crc_mapped.range(7,0));
                    send_packet4->set_control(SDP_CONTROL);

                    dll_pl_dllp_out.send_packet(send_packet4);
                    //send_packet4->dll2pl_display_sdp_packet(1);

                    wait(5,SC_NS);

                    dllp_byte1.range(7,6)=0;
                    dllp_byte1.range(5,0)=nhc_reg.range(7,2);

                    dllp_byte2.range(7,6)=nhc_reg.range(1,0);
                    dllp_byte2.range(5,4)=0;
                    dllp_byte2.range(3,0)=ndc_reg.range(11,8);

                    dllp_byte3 = ndc_reg.range(7,0);

                    send_packet5 =  new pciePacket(6);

                    send_packet5->modify_byte(0,DLLP_INITFC2_NP);
                    send_packet5->modify_byte(1,dllp_byte1);
                    send_packet5->modify_byte(2,dllp_byte2);
                    send_packet5->modify_byte(3,dllp_byte3);

                    dllp_crc_mapped=calculate_dllp_crc(send_packet5,0,4);
                    send_packet5->modify_byte(4,dllp_crc_mapped.range(15,8));
                    send_packet5->modify_byte(5,dllp_crc_mapped.range(7,0));
                    send_packet5->set_control(SDP_CONTROL);

                    dll_pl_dllp_out.send_packet(send_packet5);
                    //send_packet5->dll2pl_display_sdp_packet(1);

                    wait(5,SC_NS);

                    dllp_byte1.range(7,6)=0;
                    dllp_byte1.range(5,0)=chc_reg.range(7,2);

                    dllp_byte2.range(7,6)=chc_reg.range(1,0);
                    dllp_byte2.range(5,4)=0;
                    dllp_byte2.range(3,0)=cdc_reg.range(11,8);

                    dllp_byte3 = cdc_reg.range(7,0);

                    send_packet6 =  new pciePacket(6);

                    send_packet6->modify_byte(0,DLLP_INITFC2_CPL);
                    send_packet6->modify_byte(1,dllp_byte1);
                    send_packet6->modify_byte(2,dllp_byte2);
                    send_packet6->modify_byte(3,dllp_byte3);

                    dllp_crc_mapped=calculate_dllp_crc(send_packet6,0,4);
                    send_packet6->modify_byte(4,dllp_crc_mapped.range(15,8));
                    send_packet6->modify_byte(5,dllp_crc_mapped.range(7,0));
                    send_packet6->set_control(SDP_CONTROL);

                    dll_pl_dllp_out.send_packet(send_packet6);
                    //send_packet6->dll2pl_display_sdp_packet(1);

                    FC_INIT2_Complete=1;
                    wait(5,SC_NS);
                }

                if ( FC_INIT1_Complete & FC_INIT2_Complete )
                {
                    LOG_DEBUG << "_DLL_: FC_Init_Complete is true! \n";
                    FC_Init_Complete =1;
                    break;
                }
            } // while
        }
        catch(sc_exception &e){
            LOG_DEBUG<<"DLL: Out of fc_init";
        }
    } // fc_init 
Beispiel #30
0
static isc_result_t
isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
	isc_int32_t cntflag;

	REQUIRE(VALID_RWLOCK(rwl));

#ifdef ISC_RWLOCK_TRACE
	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
				  ISC_MSG_PRELOCK, "prelock"), rwl, type);
#endif

	if (type == isc_rwlocktype_read) {
		if (rwl->write_requests != rwl->write_completions) {
			/* there is a waiting or active writer */
			LOCK(&rwl->lock);
			if (rwl->write_requests != rwl->write_completions) {
				rwl->readers_waiting++;
				WAIT(&rwl->readable, &rwl->lock);
				rwl->readers_waiting--;
			}
			UNLOCK(&rwl->lock);
		}

		cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
		POST(cntflag);
		while (1) {
			if ((rwl->cnt_and_flag & WRITER_ACTIVE) == 0)
				break;

			/* A writer is still working */
			LOCK(&rwl->lock);
			rwl->readers_waiting++;
			if ((rwl->cnt_and_flag & WRITER_ACTIVE) != 0)
				WAIT(&rwl->readable, &rwl->lock);
			rwl->readers_waiting--;
			UNLOCK(&rwl->lock);

			/*
			 * Typically, the reader should be able to get a lock
			 * at this stage:
			 *   (1) there should have been no pending writer when
			 *       the reader was trying to increment the
			 *       counter; otherwise, the writer should be in
			 *       the waiting queue, preventing the reader from
			 *       proceeding to this point.
			 *   (2) once the reader increments the counter, no
			 *       more writer can get a lock.
			 * Still, it is possible another writer can work at
			 * this point, e.g. in the following scenario:
			 *   A previous writer unlocks the writer lock.
			 *   This reader proceeds to point (1).
			 *   A new writer appears, and gets a new lock before
			 *   the reader increments the counter.
			 *   The reader then increments the counter.
			 *   The previous writer notices there is a waiting
			 *   reader who is almost ready, and wakes it up.
			 * So, the reader needs to confirm whether it can now
			 * read explicitly (thus we loop).  Note that this is
			 * not an infinite process, since the reader has
			 * incremented the counter at this point.
			 */
		}

		/*
		 * If we are temporarily preferred to writers due to the writer
		 * quota, reset the condition (race among readers doesn't
		 * matter).
		 */
		rwl->write_granted = 0;
	} else {
		isc_int32_t prev_writer;

		/* enter the waiting queue, and wait for our turn */
		prev_writer = isc_atomic_xadd(&rwl->write_requests, 1);
		while (rwl->write_completions != prev_writer) {
			LOCK(&rwl->lock);
			if (rwl->write_completions != prev_writer) {
				WAIT(&rwl->writeable, &rwl->lock);
				UNLOCK(&rwl->lock);
				continue;
			}
			UNLOCK(&rwl->lock);
			break;
		}

		while (1) {
			cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
						     WRITER_ACTIVE);
			if (cntflag == 0)
				break;

			/* Another active reader or writer is working. */
			LOCK(&rwl->lock);
			if (rwl->cnt_and_flag != 0)
				WAIT(&rwl->writeable, &rwl->lock);
			UNLOCK(&rwl->lock);
		}

		INSIST((rwl->cnt_and_flag & WRITER_ACTIVE) != 0);
		rwl->write_granted++;
	}

#ifdef ISC_RWLOCK_TRACE
	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
				  ISC_MSG_POSTLOCK, "postlock"), rwl, type);
#endif

	return (ISC_R_SUCCESS);
}