void Revert(short value)
	{
		fValue -= value;
		if (fValue == 0 && fThreadsWaitingToBeZero > 0)
			WakeUpThread(true);
		else if (fValue > 0 && fThreadsWaitingToIncrease > 0)
			WakeUpThread(false);
	}
Ejemplo n.º 2
0
int SendMsgRequest (int type, const void *msg_stuff, int size, BOOL bBlocking, BOOL bRetain)
{
int Rc;
static int InternalSemaf = FALSE;

	// 3.34 : check if GUI is listening to notification
	// added for service edition
	// 4.05 (modify start order --> wait for console
#ifdef SERVICE_EDITION
	if (GetGuiStatus () == NOT_CONNECTED) return 0;
#else
	while (GetGuiStatus () == NOT_CONNECTED) { Sleep (100); } 
#endif

    Rc = WaitForSingleObject( hMsgRequestSemaf, INFINITE );
	assert (Rc==WAIT_OBJECT_0);

    if (bBlocking &&  hMsgRequestSemaf!=INVALID_HANDLE_VALUE)
	{
        // Request the lock to ensure all other threads are waiting
		if (Rc==WAIT_OBJECT_0)
		{
			WaitForMsgQueueToFinish (LL_ID_MSG_TO_GUI);
			// push message 
			LL_PushTypedMsg (LL_ID_MSG_TO_GUI, msg_stuff, size, type | 0x10000);
			// wake up console thread and wait until it has got the msg
			WakeUpThread (TH_CONSOLE);
			Rc = WaitForSingleObject ( hEvMsgSent, INFINITE );
			assert (Rc==WAIT_OBJECT_0);

			WaitForMsgQueueToFinish (LL_ID_MSG_TO_GUI);
			// it is done
		}
	}
	else
	{
		// do not send message while blocking message is in progress
		while (InternalSemaf)
			Sleep (1);
		// if (bRetain)
		{
			// simply push the msg into the queue and signal event to the console
			LL_PushTypedMsg (LL_ID_MSG_TO_GUI, msg_stuff, size, type);
			WakeUpThread (TH_CONSOLE);
		}
	}
	
	Rc = ReleaseMutex (hMsgRequestSemaf);
	assert (Rc!=0);

return 1;    
} // SendMsgRequest
	// We return true in case the operation causes the
	// caller to wait, so it can undo all the operations
	// previously done
	bool Add(short value)
	{
		if ((int)(fValue + value) < 0) {
			TRACE(("XsiSemaphore::Add: potentially going to sleep\n"));
			return true;
		} else {
			fValue += value;
			if (fValue == 0 && fThreadsWaitingToBeZero > 0)
				WakeUpThread(true);
			else if (fValue > 0 && fThreadsWaitingToIncrease > 0)
				WakeUpThread(false);
			return false;
		}
	}
Ejemplo n.º 4
0
//! asynchronously read the full ByteBlock and deliver it to the callback
void DispatcherThread::AsyncRead(Connection& c, const data::ByteBlockPtr& block,
                                 AsyncReadByteBlockCallback done_cb) {
    Enqueue([=, &c]() {
                dispatcher_->AsyncRead(c, block, done_cb);
            });
    WakeUpThread();
}
Ejemplo n.º 5
0
//! asynchronously read n bytes and deliver them to the callback
void DispatcherThread::AsyncRead(
    Connection& c, size_t n, AsyncReadCallback done_cb) {
    Enqueue([=, &c]() {
                dispatcher_->AsyncRead(c, n, done_cb);
            });
    WakeUpThread();
}
Ejemplo n.º 6
0
//! Register a buffered write callback and a default exception callback.
void DispatcherThread::AddWrite(
    Connection& c, const AsyncCallback& write_cb) {
    Enqueue([=, &c]() {
                dispatcher_->AddWrite(c, write_cb);
            });
    WakeUpThread();
}
Ejemplo n.º 7
0
//! Register a relative timeout callback
void DispatcherThread::AddTimer(
    const std::chrono::milliseconds& timeout, const TimerCallback& cb) {
    Enqueue([=]() {
                dispatcher_->AddTimer(timeout, cb);
            });
    WakeUpThread();
}
Ejemplo n.º 8
0
//! Register a buffered read callback and a default exception callback.
void DispatcherThread::AddRead(
    Connection& c, const AsyncCallback& read_cb) {
    Enqueue([=, &c]() {
                dispatcher_->AddRead(c, read_cb);
            });
    WakeUpThread();
}
Ejemplo n.º 9
0
void TerminateWorkerThreads (BOOL bSoft)
{
int Ark;
HANDLE tHdle[TH_NUMBER];
int nCount;
    for ( Ark=0, nCount=0 ;  Ark<TH_NUMBER ; Ark++ )
    {
	  // if bSoft do not kill management threads
	  if ( bSoft  &&  TFTPD32_MNGT_THREADS & tThreadsConfig[Ark].serv_mask)
		  continue;

      if (tThreads [Ark].gRunning)  
	  {
		  tThreads [Ark].gRunning = FALSE;
		  WakeUpThread (nCount);
          tHdle[nCount++] = tThreads [Ark].tTh;
	  } // if service is running
    }
    // wait for end of threads
    WaitForMultipleObjects (nCount, tHdle, TRUE, 5000);

    for ( Ark=0 ;  Ark<TH_NUMBER ; Ark++ )
    {
		if ( ! (bSoft  &&  TFTPD32_MNGT_THREADS & tThreadsConfig[Ark].serv_mask) )
				FreeThreadResources (Ark);
    }
    LogToMonitor ("all level 1 threads have returned\n");
} // TerminateWorkerThreads
Ejemplo n.º 10
0
//! asynchronously write TWO buffers and callback when delivered. The
//! buffer2 are MOVED into the async writer. This is most useful to write a
//! header and a payload Buffers that are hereby guaranteed to be written in
//! order.
void DispatcherThread::AsyncWrite(
    Connection& c, Buffer&& buffer, AsyncWriteCallback done_cb) {
    // the following captures the move-only buffer in a lambda.
    Enqueue([=, &c, b = std::move(buffer)]() mutable {
                dispatcher_->AsyncWrite(c, std::move(b), done_cb);
            });
    WakeUpThread();
}
Ejemplo n.º 11
0
// The "real" function called by Tftpd32 modules
int AsyncSaveKey(const char* szRegPath, const char* szKey, void* buf, int BufSize, int nType, const char* szIniFile)
{
struct S_ini msg;	
    PopulateMsg ( & msg, szRegPath, szKey, buf, BufSize, nType, szIniFile );
	LL_PushMsg (LL_ID_SETTINGS, & msg, sizeof msg);
    // tell reg thread something is to be saved
    WakeUpThread (TH_ASYNCSAVEKEY);
	return 1;
}
Ejemplo n.º 12
0
//! Terminate the dispatcher thread (if now already done).
void DispatcherThread::Terminate() {
    if (terminate_) return;

    // set termination flags.
    terminate_ = true;
    // interrupt select().
    WakeUpThread();
    // wait for last round to finish.
    thread_.join();
}
Ejemplo n.º 13
0
//! asynchronously write buffer and callback when delivered. The buffer is
//! MOVED into the async writer.
void DispatcherThread::AsyncWrite(Connection& c, Buffer&& buffer,
                                  const data::Block& block,
                                  AsyncWriteCallback done_cb) {
    // the following captures the move-only buffer in a lambda.
    Enqueue([=, &c,
              b1 = std::move(buffer), b2 = block]() mutable {
                dispatcher_->AsyncWrite(c, std::move(b1));
                dispatcher_->AsyncWrite(c, b2, done_cb);
            });
    WakeUpThread();
}
Ejemplo n.º 14
0
void QtMediaPlayerJNI::play()
{
    JNIEnv* env;

    if (m_javaVM->AttachCurrentThread(&env, NULL)<0)
    {
        qCritical()<<"AttachCurrentThread failed";

    }
    WakeUpThread();
    env->CallVoidMethod(fields.m_qtMediaPlayerObject(),fields.m_playID);

}
Ejemplo n.º 15
0
// frees an item (may crash if allocation in progess)
void DHCPDestroyItem (struct LL_IP *pCur)
{
	if (pCur!=NULL)
	{
		LOG (5, "Freeing item %s %s", 
							 inet_ntoa (pCur->dwIP),
							 haddrtoa  (pCur->sMacAddr, 6,':') ) ;
		// put item at the end of the list and resort array
		SetIP(pCur, INADDR_NONE);   // will be the last item
		memset(pCur->sMacAddr, 0, 6);
		qsort (tFirstIP, nAllocatedIP, sizeof *tFirstIP, QsortCompare);
		qsort (tMAC, nAllocatedIP, sizeof *tMAC, MACCompare);
		DecNumAllocated(); 
		ReorderLeases();
		free ( tFirstIP[nAllocatedIP] ); // free the last item
	}
 // wake up DHCP thread --> actualizes GUI with SendLeases
    WakeUpThread (TH_DHCP);
} // DHCPDestroyItem
Ejemplo n.º 16
0
//! Cancel all callbacks on a given connection.
void DispatcherThread::Cancel(Connection& c) {
    Enqueue([this, &c]() {
                dispatcher_->Cancel(c);
            });
    WakeUpThread();
}
Ejemplo n.º 17
0
static int ProcessMsg (SOCKET s, const struct S_ConsoleMsg *pmsg)
{
struct LL_TftpInfo *pTftp;
int                 uServices;

LogToMonitor ("TFTPd console receive msg %d\n", pmsg->type);
    switch (pmsg->type)
    {
        case C_CONS_KILL_TRF :
            LOG (1, "transfer %d must be killed", pmsg->u.kill.dwTransferId);
            for ( pTftp=pTftpFirst ; 
                  pTftp!=NULL && pTftp->tm.dwTransferId != pmsg->u.kill.dwTransferId ;
                  pTftp = pTftp->next );
			if (pTftp != NULL) { nak (pTftp, ECANCELLED); pTftp->st.ret_code=TFTP_TRF_STOPPED; }
            break;
            
        case C_TFTP_TERMINATE :
LogToMonitor ("terminating TFTP service\n");
            tThreads[TH_TFTP].gRunning = FALSE;
            WakeUpThread (TH_TFTP);
            break;
        
        case C_DHCP_TERMINATE :
LogToMonitor ("terminating DHCP service\n");
            tThreads[TH_DHCP].gRunning = FALSE;
            // wake up DHCP thread
	        WakeUpThread (TH_DHCP);
            break;
            
        case C_TERMINATE :
LogToMonitor ("stopping services\n");
            TerminateWorkerThreads (FALSE); // keep management threads
            break;  

        case C_SUSPEND :
LogToMonitor ("suspending services\n");
            TerminateWorkerThreads (TRUE); // keep management threads
            break;            
            
        case C_START :
LogToMonitor ("starting services\n");
			StartMultiWorkerThreads (TRUE);
            break;            
            
        case C_DHCP_RRQ_SETTINGS :
LogToMonitor ("sending DHCP settings\n");
            SendMsg (s, C_DHCP_RPLY_SETTINGS, & sParamDHCP, sizeof sParamDHCP);
            break;
            
        case C_TFTP_RRQ_SETTINGS :
LogToMonitor ("sending TFTP settings\n");
            SendMsg (s, C_TFTP_RPLY_SETTINGS, & sSettings, sizeof sSettings);
            break;
            
        case C_DHCP_WRQ_SETTINGS :
LogToMonitor ("storing new DHCP settings\n");
            DHCPSaveConfig ( & pmsg->u.dhcp_settings );
            break;
            
        case C_TFTP_WRQ_SETTINGS :
LogToMonitor ("storing new TFTP settings\n");
			{static struct S_RestartTable sRestart;
			    sRestart.newservices = pmsg->u.tftp_settings.uServices;
				sRestart.oldservices = sSettings.uServices;
				sRestart.flapservices = 0;
				if (   sSettings.Port != pmsg->u.tftp_settings.Port
		            || lstrcmp (sSettings.szTftpLocalIP, pmsg->u.tftp_settings.szTftpLocalIP )!=0 )
					sRestart.flapservices |= TFTPD32_TFTP_SERVER;
				// restart syslog if its settings log has changed
				if (     sSettings.uServices &  TFTPD32_SYSLOG_SERVER 
					  && (   sSettings.bSyslogPipe != pmsg->u.tftp_settings.bSyslogPipe
					      || strcmp(sSettings.szSyslogFile,pmsg->u.tftp_settings.szSyslogFile)!= 0 )
				   )
					 sRestart.flapservices |= TFTPD32_SYSLOG_SERVER;

            sSettings = pmsg->u.tftp_settings;

            if ( IsValidDirectory ( pmsg->u.tftp_settings.szBaseDirectory ) )
                    lstrcpyn ( sSettings.szWorkingDirectory, 
                               pmsg->u.tftp_settings.szBaseDirectory, 
                               sizeof sSettings.szWorkingDirectory );
			_beginthread ( Tftpd32UpdateServices, 0, (void *) & sRestart );            
			Tftpd32SaveSettings ();
			}
			break;

        case C_TFTP_RESTORE_DEFAULT_SETTINGS :
LogToMonitor ("restore default settings\n");
            Tftpd32DestroySettings ();
            break;
            
        case C_TFTP_CHG_WORKING_DIR :
LogToMonitor ("changing working directory to <%s>\n", pmsg->u.working_dir);
            if ( IsValidDirectory ( pmsg->u.working_dir ) )
                    lstrcpyn ( sSettings.szWorkingDirectory, 
                               pmsg->u.working_dir, 
                               sizeof sSettings.szWorkingDirectory );
            break;
        case C_RRQ_WORKING_DIR :
LogToMonitor ("sending working directory <%s>\n", sSettings.szWorkingDirectory);
            SendMsg (s, C_REPLY_WORKING_DIR, 
                     sSettings.szWorkingDirectory, 
                     1 + lstrlen (sSettings.szWorkingDirectory) );
            break;
        
        case C_DELETE_ASSIGNATION :
LogToMonitor ("deleting DHCP entry %X\n", pmsg->u.del_lease.ip);
            { struct in_addr  addr;
              BOOL   dummy;
                addr.s_addr = pmsg->u.del_lease.ip;
                DHCPDestroyItem ( DHCPSearchByIP ( & addr, &dummy  ) );
            }
            break;

		case C_RRQ_GET_SERVICES :
LogToMonitor ("sending running services\n");
			uServices = GetRunningThreads ();
            SendMsg (s, 
				     C_REPLY_GET_SERVICES, 
					 & uServices,
					 sizeof uServices );
            break;

		case C_RRQ_GET_INTERFACES :
LogToMonitor ("sending IP interfaces");
			AnswerIPList ();
			break;

        case C_RRQ_DIRECTORY_CONTENT :
LogToMonitor ("sending Directory content");
            SendDirectoryContent ();
            break;

        case C_TFTP_GET_FULL_STAT :
LogToMonitor ("sending Directory content");
            ConsoleTftpGetStatistics ();
            break;

		default :
LogToMonitor ("Service received unknown message %d\n", pmsg->type);
            break;

    }   
return 1;    
} // ReadMsg
Ejemplo n.º 18
0
CThreadManager::TaskId CThreadManager::BeginTaskComplex(
	CThreadUnit* pThread,GrupId gidMy,const STasksGrup* pTasks,int nCountTassks,int nCountCoin)
{

	STask ta;
	ta.m_taskId=pThread;
	ta.m_Grup=gidMy;
	ta.m_nCountCoinReady=ta.m_nCountCoin=nCountCoin;
	ta.m_arDefsTasks.assign(pTasks,pTasks+nCountTassks);
	{
		//Считаем сколько задач нужно ждать
		int nW=0;
		for(int i=0;i<nCountTassks;++i)
		{
			if(pTasks[i].m_bGrup)
				nW+=pTasks[i].m_nCount;
			else
				++nW;

		}

		ta.m_etiState=  nW  ? etiWaitPrev : etiWaitThread;
		ta.m_arTasks.resize(nW);
	}

	pThread->m_GrupId=gidMy;
	pThread->m_pThreadManager=this;

	boost::lock_guard<boost::mutex> l(m_cs);
	m_arTask[ta.m_taskId]=ta;
	STask &t=GetTask(ta.m_taskId);

	if(t.m_etiState==etiWaitPrev)
	{ //ищем все предшествующие задачи
		int nPosOut=0;
		int nIns=0;
		for(unsigned i=0;i<t.m_arDefsTasks.size();++i)
		{
			const STasksGrup &tg=t.m_arDefsTasks[i];
			if(tg.m_bGrup)
			{
				for(int j=0;j<tg.m_nCount;++j)
				{
					 //Ищем готовую групп
					for(CTasks::iterator ti=m_arTask.begin();ti!=m_arTask.end();++ti)
					{
						//if(ti->m_etiState==etiReadyUnкnown && ti->m_Grup==tg.m_gidAfter)
						if(ti->second.m_etiState == etiReadyUnknown  &&  ti->second.m_Grup==tg.m_gidAfter)
						{

							if(std::find(&t.m_arTasks[0],&t.m_arTasks[nPosOut],ti->second.m_taskId)!=&t.m_arTasks[nPosOut])  //убираем зацикливание
							{
								t.m_arTasks[nPosOut]=ti->second.m_taskId;
								if(--ti->second.m_nCountCoin == 0)
								{
									ti->second.m_etiState=etiReady;
									++nIns;
								}
								break;
							}
						}
					}
					++nPosOut;
				}

			}
			else
			{
				STask &to=GetTask(tg.m_pThreadAfter);
				if(to.m_etiState==etiReadyUnknown)
				{
					t.m_arTasks[nPosOut]=to.m_taskId;
					if(--to.m_nCountCoin == 0)
					{
						to.m_etiState=etiReady;
						++nIns;
					}

				}
				++nPosOut;
			}

		}
		if(nPosOut==nIns)
			t.m_etiState=etiWaitThread;

	}



	if(t.m_etiState==etiWaitThread)
		WakeUpThread();

	return pThread;
}
Ejemplo n.º 19
0
/*++
Function:
  SetEvent

See MSDN doc.
--*/
BOOL
PALAPI
SetEvent(
    IN HANDLE hEvent)
{
    BOOL bRet = TRUE;
    Event *pEvent;
    GLOBAL_EVENT_SYSTEM_OBJECT *pEventInfo;
    SHMPTR pTemp;
    ThreadWaitingList *pWaitingThread;

    PERF_ENTRY(SetEvent);
    ENTRY("SetEvent(hEvent=%p)\n", hEvent);

    pEvent = (Event *) HMGRLockHandle2(hEvent, HOBJ_EVENT);
    if(NULL == pEvent)
    {
        ERROR("Unable to lock handle %p!\n", hEvent);
        SetLastError(ERROR_INVALID_HANDLE);
        LOGEXIT("SetEvent returns BOOL %d\n",FALSE);
        PERF_EXIT(SetEvent);
        return FALSE;
    }

    SHMLock();

    pEventInfo = (GLOBAL_EVENT_SYSTEM_OBJECT*) SHMPTR_TO_PTR(pEvent->info);

    if (pEventInfo == NULL)
    {
        ASSERT("Invalid shared memory pointer\n");
        SetLastError(ERROR_INTERNAL_ERROR);
        bRet = FALSE;
        goto SetEventExit;
    }

    if (!pEventInfo->state)
    {
        DWORD *pAwakenState;
        SHMPTR shmWaitingThread;
        ThreadWaitingList *prevThread = NULL;

        pEventInfo->state = TRUE;

        shmWaitingThread = pEventInfo->waitingThreads;

        /* wake up waiting threads */
        while (shmWaitingThread)
        {
            pWaitingThread = SHMPTR_TO_PTR(shmWaitingThread);

            if (pWaitingThread == NULL)
            {
                ASSERT("Invalid shared memory pointer\n");
                SetLastError(ERROR_INTERNAL_ERROR);
                bRet = FALSE;
                goto SetEventExit;
            }

            /* check whether thread is already awake. this can happen if
               another object already woke up the thread, but the thread hasn't
               yet had time to remove itself from all waiting lists. */
            pAwakenState = SHMPTR_TO_PTR(pWaitingThread->state.shmAwakened);

            if(!THREADInterlockedAwaken(pAwakenState, FALSE))
            {
                TRACE("thread is already awake, skipping it\n");
                prevThread = pWaitingThread;
                shmWaitingThread = pWaitingThread->ptr.shmNext;
                continue;
            }

            /* remove thread from waiting list */
            pTemp = shmWaitingThread;
            shmWaitingThread = pWaitingThread->ptr.shmNext;
            if(NULL == prevThread)
            {
                pEventInfo->waitingThreads = shmWaitingThread;
            }
            else
            {
                prevThread->ptr.shmNext = shmWaitingThread;
            }

            TRACE("Waking up thread(%#x) Event has been set (%p)\n",
                  pWaitingThread->threadId, hEvent);

            WakeUpThread(pWaitingThread->threadId,
                         pWaitingThread->processId,
                         pWaitingThread->blockingPipe,
                         WUTC_SIGNALED );

            SHMfree(pTemp);

            /* if the event is auto-reset, we only want to wake up one thread,
               so break out.*/
            if (pEventInfo->manualReset == FALSE)
            {
                pEventInfo->state = FALSE;
                break;
            }
        }
    }

SetEventExit:
    SHMRelease();
    HMGRUnlockHandle(hEvent, &pEvent->objHeader);

    LOGEXIT("SetEvent returns BOOL %d\n", bRet);
    PERF_EXIT(SetEvent);
    return bRet;
}