示例#1
0
__bool CWaitableTransaction::Wait(__uint TimeOut, __bool ProcessMessage)
{
#ifdef _WIN32
	DWORD res;

	InterlockedIncrement((PLONG)&m_iRefcount);
	if(ProcessMessage){		
		bool bExit = false;
		RTK_TIME tm, now;
		rtk_time_mark(&tm);
		HANDLE hEvent = Event.Handle();
		while(!bExit){
			res = MsgWaitForMultipleObjects(
				1, &hEvent, FALSE, TimeOut, QS_ALLEVENTS
				);
			switch(res){
			case WAIT_OBJECT_0:
				bExit = true;
				break;
			case WAIT_TIMEOUT:
				bExit = true;
				break;
			case WAIT_OBJECT_0 + 1:
				rtk_time_mark(&now);
				double elapsed = rtk_time_diff(&now, &tm) * 1000;
				tm = now;
				if(TimeOut > elapsed){
					TimeOut -= (__uint)elapsed;
				}else{
					bExit = true;
					res = WAIT_TIMEOUT;
					break;
				}
				MSG msg;
				while(PeekMessage(&msg, 0, 0, 0, TRUE)){
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				break;
			}
		}		
	}else{
		res = Event.Wait(TimeOut);
	}
	m_bWaitResult = res == WAIT_OBJECT_0? __true : __false;
	InterlockedDecrement((PLONG)&m_iRefcount);
	return m_bWaitResult;
#else
	m_bWaitResult =  Event.Wait(TimeOut) ==WAIT_OBJECT_0? __true : __false;
#endif
}
示例#2
0
void CTransactionContainer::reap()
{
	WriteLock();
	CTList::iterator p;
	p=tlist.begin();	
	double diff;
	RTK_TIME tm;
	CTransaction *t;
	rtk_time_mark(&tm);
	while(p!=tlist.end()){			  
		t = *p;
		assert(&(*p)->birth == &((*p)->birth));
		diff = rtk_time_diff(&tm,&((*p)->birth));
		if(diff > t->life && !t->m_iRefcount){
			p=tlist.erase(p);
			char guid_name[128];
			t->Guid.to_string(guid_name);
			DEBUG_PRINTF((
				">>T %s,too old(%.0f>%.0f),removing.\n",
				guid_name,diff, t->life
				));
			t->OnTimeout();
			delete t;
		}else{
			p++;
		}
	}
	Release();
}
示例#3
0
CTransaction::CTransaction()
{
	Guid.create();
	rtk_time_mark(&birth);
	m_iRefcount = 0;
	m_Parent = 0;
	life = g_TransactionLife;
}
示例#4
0
void CPacketMan::reap_packets()
{
	RTK_TIME	now;
	rtk_time_mark(&now);

	reap_sent(&now);
	reap_received(&now);
}
示例#5
0
__uint _fastcall _read_tags(
	__uint count, 
	PCTAG_NAME names, 
	Ppmc_value_t values,
	__uint & existed
	)
{
	RTK_CURSOR	hNode, hTag;
	NODE_KEY	cachedNode;
	RTK_TAG		*pTag;
	__uint		i, valids;

	valids = 0;
	existed = 0;
	ZeroMemory(values, sizeof(values[0]) * count);
	if(!lock_rtdb(false, 1000)){
		return 0;
	}
	hNode = 0;
	hTag = 0;
	RTK_TIME now;
	rtk_time_mark(&now);
	hNode = 0;
	memset(&cachedNode, 0, sizeof(cachedNode));
	for(i=0; i<count; i++){
		if(!(cachedNode == names[i].node)){
			close_handle(hNode);
			hNode = 0;			
		}
		if(!hNode){
			hNode = open_node(&names[i].node);
			cachedNode = names[i].node;
		}
		if(!hNode){
			values[i].Flags &= ~TF_Valid;
			continue;
		}		
		hTag = open_tag(hNode, &names[i].sname);
		if(hTag){
			existed++;
			pTag = (RTK_TAG*)cursor_get_item(hTag);
			double diff;
			diff = rtk_time_diff(&now, &pTag->d.CachedTime);
			if(diff > (g_fltTagLife*2)){
				mark_expired(pTag);
			}
			values[i] = pTag->d.Value;
			valids++;
			close_handle(hTag);
		}else{
			values[i].Flags &= ~TF_Valid;
		}		
	}
	close_handle(hNode);
	unlock_rtdb();
	return valids;
}
示例#6
0
void CPacketMan::dbg_dump()
{
	RECEIVE_ITEM *h;
	RITEM_LIST::iterator p;
	RTK_TIME now;
	int i=0;
	SITEM_LIST::iterator sit;
	SEND_ITEM *si;
	PRTK_LIST_ENTRY entry, headEntry;

	rtk_time_mark(&now);
	if(r_lst.size()){
		utils_error("%d packets under construction:-->\n", r_lst.size());
		p = r_lst.begin();		
		
		while(p != r_lst.end()){
			headEntry = &(p->second);
			entry = headEntry->Flink;
			while(entry != headEntry){
				h = RTK_CONTAINING_RECORD(entry, RECEIVE_ITEM, li);
				utils_error("NO.%d, Age=%.3f, life=%.3f, ", 
					i,
					rtk_time_diff(&now, &h->birthday),
					h->life
					);
				utils_error("Got %d of Total %d fragments, size %d bytes\n", 
					h->header->total_frag - h->unreceived_fragments,
					h->header->total_frag,
					h->header->data_size
					);
				entry = entry->Flink;
			}
			p++;
			i++;
		}
	}
	if(s_lst.size()){
		utils_error("%d packets in send queue:------>\n", s_lst.size());
		sit = s_lst.begin();
		i = 0;
		while(sit != s_lst.end()){
			headEntry = &sit->second;
			entry = headEntry->Flink;
			while(entry != headEntry){
				si = RTK_CONTAINING_RECORD(entry, SEND_ITEM, li);
				entry = entry->Flink;
				utils_error("No.%d, %d fragments, age=%.3f, life=%.3f\n", 
					i, si->header->total_frag, rtk_time_diff(&now, &si->birthday),
					si->life
					);
				i++;
			}
			sit++;
		}
	}
}
double CExpression::vexp ( arbore a )
{
	double v;
	SYSTEMTIME tm;
	
	GetSystemTime(&tm);

	if (a->operatie==NULL) {error_code=10;return 0;}
	switch(a->operatie){
	case '+' : return( vexp(a->left)+vexp(a->right) );
	case '-' : return( vexp(a->left)-vexp(a->right) );
	case '*' : return( vexp(a->left)*vexp(a->right) );
	case '%':
		{
			v = vexp(a->right);
			if(v == 0){
				error_code = DIVISION_BY_0;
				return 0;
			}
			return (int)vexp(a->left) % (int)v;
		}
	case '/' : v=vexp(a->right) ;
		if (v==0){
			error_code=DIVISION_BY_0;
			return -vexp(a->left)/0.001;
		}else{
			return(vexp(a->left)/v);
		}
	case 150 : return(sin(vexp(a->left)));
	case 151 : return(cos(vexp(a->left)));
	case 152 : return(exp(vexp(a->left)));
	case 153 : v=vexp(a->left) ;
		if (v<0) {error_code=INVALID_DOMAIN;return 0;}
		else return(sqrt(v));
	case 154 : v=vexp(a->left) ;
		if (v<=0) {error_code=INVALID_DOMAIN;return 0;}
		else return(log(v));
	case 155 : return (tan (vexp(a->left)));
	case 156 : return (1 / tan (vexp(a->left)));
	case 157 : return (asin (vexp(a->left)));
	case 158 : return (acos (vexp(a->left)));
	case 159 : return (atan (vexp(a->left)));
	case 173 : return (fabs (vexp(a->left)));
	case 160 : return tm.wYear;
	case 161 : return tm.wMonth;
	case 162 : return tm.wDay;
	case 163 : return tm.wHour;
	case 164 : return tm.wMinute;
	case 165 : return tm.wSecond;
	case 166 : return max(vexp(a->left),vexp(a->right));
	case 167 : return min(vexp(a->left),vexp(a->right));
	case 168 : return rng_rand(0,RAND_MAX)*vexp(a->left)/RAND_MAX;
	//case '|' : return(fabs(vexp(a->left)));
	case '^' : return(pow(vexp(a->left),vexp(a->right)));
	case '@' : return (a->valoare);
		//logical operations evaluation
	case '<' : return( vexp(a->left) < vexp(a->right) );
	case '>' : return( vexp(a->left) > vexp(a->right) );
	case '!' : return(!vexp(a->right)) ;
	// added by chenj, @2008-5-22
	case '=' : return( vexp(a->left) == vexp(a->right) );
	case '&' : return (int)(vexp(a->left)) & (int)(vexp(a->right));
	case '|' : return (int)(vexp(a->left)) | (int)(vexp(a->right));
		
	case 169:
		{
			RTK_TIME t;
			rtk_time_mark(&t);
			return (double)(__int64)t.Data / 1e7;
		}
		
	case 170:
		{
			/* last update time */
			PRTK_TAG tte;
			__r8 retval = 0;
			
			tte  = (PRTK_TAG)a->left->pvObj;
			if(!tte){
				error_code=UNDEFINED_VARIABLE;
				retval = 0;
			}else{ 
				if(!(tte->d.Value.Flags & TF_Valid)){
					error_code=UNDEFINED_VARIABLE;
					retval = 0;
				}else{
					PRTK_TIME pTime = (PRTK_TIME)&tte->d.BinaryAddress[8];
					retval = (double)(__int64)pTime->Data / 1e7;
					rtk_time_mark(pTime);
				}
			}

			return retval;
		}

	case 171  : 
		{
			// a database tag
			PRTK_TAG tte;
			__r8 retval = 0;
			tte = (PRTK_TAG)a->pvObj;
			if(!tte){
				error_code=UNDEFINED_VARIABLE;
				retval = 0;
			}else{ 
				if(!(tte->d.Value.Flags & TF_Valid)){
					error_code=UNDEFINED_VARIABLE;
					retval = 0;
				}else{
					pmc_value_t dblVal;
					set_value_type(dblVal.Flags, dt_real8);
					pmc_type_cast(&tte->d.Value, &dblVal);
					retval = dblVal.Value.dbl;
				}
			}
			return retval;
		}
	
	case 172:
		{
			/* span time */
			PRTK_TAG tte;
			RTK_TIME now;
			__r8 retval = 0;
			
			tte  = (PRTK_TAG)a->left->pvObj;
			if(!tte){
				error_code=UNDEFINED_VARIABLE;
				retval = 0;
			}else{ 
				if(!(tte->d.Value.Flags & TF_Valid)){
					error_code=UNDEFINED_VARIABLE;
					retval = 0;
				}else{
					PRTK_TIME pTime = (PRTK_TIME)&(tte->d.BinaryAddress[8]);
					rtk_time_mark(&now);
					if(pTime->Data != 0){
						/* yes, the field is previouly stored with a resonable value,
						thus valid for a sub-operation to get a duration time */
						retval = rtk_time_diff(&now, pTime);
					}else{
						/* this might be the first time that a time-span was requested
						for this tag
						*/
						retval = 0;
					}
					
					*pTime = now;
				}
			}

			return retval;
		}

	}

	return 0;
}
示例#8
0
/*
	MergePacket()
	
	if an incoming packet belongs to a large packet(thus a fragment), 
	merge it with previously received fragments, then make a second 
	decision whether all fragments of the large packet has been received.
*/
RECEIVE_ITEM * CPacketMan::MergePacket(RTK_PACKET * input_packet)
{
	RECEIVE_ITEM *ri;
	RITEM_LIST::iterator p;
	std::pair<RITEM_LIST::iterator, bool> pr;
	__uint packetSize;
	PRTK_LIST_ENTRY headEntry, entry;
	
	assert(IsFragment(input_packet));

	packetSize = input_packet->total_frag * m_mtu + sizeof(RECEIVE_ITEM);
	
	p = r_lst.find(input_packet->guid);
	
	if(p != r_lst.end()){
		headEntry = entry = p->second.Flink;
		do{
			ri = RTK_CONTAINING_RECORD(entry, RECEIVE_ITEM, li);
			entry = entry->Flink;
		}while(entry != headEntry && ri->header->grp_id != input_packet->grp_id);
			
		if(ri->header->grp_id != input_packet->grp_id){
			ri = 0;
		}
	}else{
		ri = 0;
		headEntry = 0;
	}

	if(!ri){
		/*
			ok, this is the first arriving fragment of the large packet
			perhaps also the first group, if existed

			a new node must be allocated
		*/
		ri = (RECEIVE_ITEM*)Alloc(packetSize);
		if(!ri){
			return 0;
		}

		memset(ri, 0, sizeof(RECEIVE_ITEM));

		if(headEntry){
			// new member of the group, chain them
			RtkInsertTailList(headEntry, &ri->li);
		}else{
			static RTK_LIST_ENTRY theFirstEntry;
			// first packet in the group, add to list
			pr = r_lst.insert(RITEM_LIST::value_type(input_packet->guid, theFirstEntry));
			if(!pr.second){
				Free(ri);
				return 0;
			}
			headEntry = &pr.first->second;
			RtkInitializeListHead(headEntry);
			RtkInsertTailList(headEntry, &ri->li);
		}
		
		ri->header = (PRTK_PACKET)(ri + 1);

		// copy input_packet to header
		*ri->header = *input_packet;
		// and modify some fields
		rtk_time_mark(&ri->birthday);
		ri->life = rtkm_receive_fragments_life * input_packet->total_frag;
		ri->unreceived_fragments = ri->header->total_frag;
		ri->header->data_size = 0;
		ri->header->frgmt_id = 0;
	}
	
	// put the packet into the RECEIVE_ITEM
	
	ri->max_frgmt_id_received >= input_packet->frgmt_id?
		0 : ri->max_frgmt_id_received = input_packet->frgmt_id;

	if(ri->header->total_frag > input_packet->frgmt_id){
		ri->header->data_size += input_packet->data_size;
		ri->bitmap[input_packet->frgmt_id] = 1;
		memcpy(
			ri->header->data + input_packet->offset, 
			input_packet->data, 
			input_packet->data_size
			);
		ri->unreceived_fragments--;
	}else{
		// a fragment claiming a segid larger than the total
		// segment count, simply discard this arrogant
		// fragment.

		// 2004/11/1, we should have already checked against 
		// this in WillingToAccept, so, just assert here
		assert(0);
	}
	
	return ri;
}
示例#9
0
/*
	generate a fragment list for a large data packet
	
	2004/8/2 jackie
	----------------------------------------------------
	now we're to fix a bug when multiple calls of SplitPacket
	with the same guid is being made, this is not impossible as it
	might look like. The server process is often in a loop servicing
	some clients, in each round of the loop it gives out some data,
	note the data is sent over vbus layer using the same GUID that
	the client is expecting. In this case, if the sent data is large
	enough it must go to this place to be split, so we can see the send
	operation is bound to fail because the s_lst won't permit another
	send_item with a same GUID.

	If we got another packet with a same GUID, we append the
	latter one to the previous ones in the queue.
	
	Because the client might be incidently calling send_rtk_data_with_guid
	twice, in which case the appending is not desired, so we need
	the client's explicit statement that appending is permited, we
	use a new flag in packet_type.

	The new flag also serves as a guarding flag to the s_lst reaper
	that the packet is not to be deleted, because some other fragments
	is just on the way to send_rtk_data_with_guid.
*/
SEND_ITEM *CPacketMan::SplitPacket(const RTK_PACKET *input)
{
	char *heap, *p;
	__uint fragments, header_size, last_data_size, heap_size;
	int i, offset, effective_load;
	RTK_PACKET * frag;
	SEND_ITEM * si, * previousItem;
	SITEM_LIST::iterator pit;
	std::pair<SITEM_LIST::iterator, bool> pr;
	PRTK_LIST_ENTRY headEntry, entry;
	__u16 groupId;

	pit = s_lst.find(input->guid);
	if(pit != s_lst.end()){
		headEntry = &pit->second;
		entry = headEntry->Blink;
		assert(!RtkIsListEmpty(entry));
		previousItem = RTK_CONTAINING_RECORD(entry, SEND_ITEM, li);
		if(!(previousItem->header->packet_type & PF_PacketGroup)){
			/*
				sending another packet of the same GUID without
				group flag set is not permited.
			*/
			return NULL;
		}
		groupId = previousItem->header->grp_id + 1;
	}else{
		previousItem = NULL;
		si = 0;
		headEntry = 0;
		groupId = 0;
	}
	
	// calculate size needed
	header_size = sizeof(RTK_PACKET) - sizeof(input->data);
	effective_load = m_mtu - header_size;
	fragments = (input->data_size + effective_load - 1) / effective_load;
	heap_size = fragments * m_mtu;
	heap_size += sizeof(SEND_ITEM);

	// create the send_item
	heap = (char *)Alloc(heap_size);
	if(!heap){
		return 0;
	}
	
	si = (SEND_ITEM*)heap;
	memset(si, 0, sizeof(SEND_ITEM));

	si->header = (RTK_PACKET*)(si + 1);

	// insert the send_item into the s_lst
	if(!headEntry){
		static RTK_LIST_ENTRY theFirstEntry;
		pr = s_lst.insert(SITEM_LIST::value_type(input->guid, theFirstEntry));
		if(!pr.second){
			Free(heap);
			return 0;
		}
		headEntry = &pr.first->second;
		RtkInitializeListHead(headEntry);
		RtkInsertTailList(headEntry, &si->li);
	}else{
		// appending the fragments to the existing item
		RtkInsertTailList(headEntry, &si->li);
	}
	
	last_data_size = input->data_size % effective_load;
	offset = 0;
	for(i = 0, p = (char*)si->header, frag = (RTK_PACKET*)p; 
		i<fragments; 
		i++, p += m_mtu, frag = (RTK_PACKET*)p, offset += effective_load
	){
		// copy contents of input_packet to fragment
		*frag			= *input;
		// then modify some fields
		frag->frgmt_id		= i;
		frag->total_frag 	= fragments;
		frag->data_size 	= i==fragments-1? last_data_size : effective_load;
		frag->offset		= offset;
		frag->grp_id		= groupId;
		memcpy(frag->data, input->data + offset, frag->data_size);
	}

	rtk_time_mark(&si->birthday);
	si->life = rtkm_send_fragments_life * fragments;
	if(input->packet_type & PF_PacketGroup){
		si->life *= 5;
	}

	return si;
}