Example #1
0
ThreadReturnType BaseTCPServer::TCPServerLoop(void* tmp) {
#ifdef _WINDOWS
	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
#endif
	if (tmp == 0) {
		THREAD_RETURN(nullptr);
	}
	BaseTCPServer* tcps = (BaseTCPServer*) tmp;

#ifndef WIN32
	_log(COMMON__THREADS, "Starting TCPServerLoop with thread ID %d", pthread_self());
#endif

	tcps->MLoopRunning.lock();
	while (tcps->RunLoop()) {
		Sleep(SERVER_LOOP_GRANULARITY);
		tcps->Process();
	}
	tcps->MLoopRunning.unlock();

#ifndef WIN32
	_log(COMMON__THREADS, "Ending TCPServerLoop with thread ID %d", pthread_self());
#endif

	THREAD_RETURN(nullptr);
}
Example #2
0
thread_return_t BaseTCPServer::TCPServerLoop( void* arg )
{
    BaseTCPServer* tcps = reinterpret_cast<BaseTCPServer*>( arg );
    assert( tcps != NULL );

    THREAD_RETURN( tcps->TCPServerLoop() );
}
Example #3
0
THREAD_PROTO(cleanupTask,arg)
{
   msocket_server_t *self = (msocket_server_t *) arg;
   if(self != 0)
   {
      if (self->pDestructor == 0)
      {
         THREAD_RETURN(0);
      }
      while(1)
      {
         int8_t rc;
         uint8_t stopThread;
         SLEEP(200); //sleep 200ms
         rc = _sem_test(&self->sem);
         if(rc < 0)
         {
            //failure
            printf("Error in cleanupTask, errno=%d\n",errno);
            break; //break while-loop
         }
         else if(rc > 0)
         {
            //successfully decreased semaphore, this means that there must be something in the array
            void *item;
            MUTEX_LOCK(self->mutex);
            assert(adt_ary_length(&self->cleanupItems)>0);
            item = adt_ary_shift(&self->cleanupItems);
            self->pDestructor(item);
            MUTEX_UNLOCK(self->mutex);
         }
         else
         {
            //failed to decrease semaphore, check if time to close
            MUTEX_LOCK(self->mutex);
            stopThread = self->cleanupStop;
            MUTEX_UNLOCK(self->mutex);
            if(stopThread)
            {
               break; //break while-loop
            }
         }
      }
   }
   THREAD_RETURN(0);
}
ThreadReturnType TCPConnection::TCPConnectionLoop(void* tmp)
{
#ifdef _WINDOWS
	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
#endif
	if (tmp == 0)
	{
		THREAD_RETURN(nullptr);
	}
	TCPConnection* tcpc = (TCPConnection*) tmp;
#ifndef WIN32
	//Log.Out(Logs::Detail, Logs::TCP_Connection, "%s Starting TCPConnectionLoop with thread ID %d", __FUNCTION__, pthread_self());
#endif
	tcpc->MLoopRunning.lock();
	while (tcpc->RunLoop())
	{
		Sleep(LOOP_GRANULARITY);
		if (!tcpc->ConnectReady())
		{
			if (!tcpc->Process())
			{
				//the processing loop has detecting an error..
				//we want to drop the link immediately, so we clear buffers too.
				tcpc->ClearBuffers();
				tcpc->Disconnect();
			}
			Sleep(1);
		}
		else if (tcpc->GetAsyncConnect())
		{
			tcpc->SetAsyncConnect(false);
		}
		else
		{
			Sleep(10);	//nothing to do.
		}
	}
	tcpc->MLoopRunning.unlock();

#ifndef WIN32
	//Log.Out(Logs::Detail, Logs::TCP_Connection, "%s Ending TCPConnectionLoop with thread ID %d", __FUNCTION__, pthread_self());
#endif
	THREAD_RETURN(nullptr);
}
Example #5
0
static THREAD_FN
load_deferred_queue(void *arg)
{
	struct deferred_test_data *data = arg;
	size_t i;

	for (i = 0; i < CB_COUNT; ++i) {
		event_deferred_cb_init(&data->cbs[i], deferred_callback, NULL);
		event_deferred_cb_schedule(data->queue, &data->cbs[i]);
		SLEEP_MS(1);
	}

	THREAD_RETURN();
}
Example #6
0
ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs)
{
	EQStreamFactory *fs=(EQStreamFactory *)eqfs;

#ifndef WIN32
	Log.Out(Logs::Detail, Logs::None,  "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
#endif

	fs->WriterLoop();

#ifndef WIN32
	Log.Out(Logs::Detail, Logs::None,  "Ending EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
#endif

	THREAD_RETURN(nullptr);
}
Example #7
0
ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs)
{
	EQStreamFactory *fs=(EQStreamFactory *)eqfs;

#ifndef WIN32
	_log(COMMON__THREADS, "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
#endif

	fs->WriterLoop();

#ifndef WIN32
	_log(COMMON__THREADS, "Ending EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
#endif

	THREAD_RETURN(nullptr);
}
Example #8
0
static THREAD_FN
register_events_subthread(void *arg)
{
	struct timeval tv = {0,0};
	SLEEP_MS(100);
	event_active(&time_events[0], EV_TIMEOUT, 1);
	SLEEP_MS(100);
	event_active(&time_events[1], EV_TIMEOUT, 1);
	SLEEP_MS(100);
	tv.tv_usec = 100*1000;
	event_add(&time_events[2], &tv);
	tv.tv_usec = 150*1000;
	event_add(&time_events[3], &tv);
	SLEEP_MS(200);
	event_active(&time_events[4], EV_TIMEOUT, 1);

	THREAD_RETURN();
}
Example #9
0
static THREAD_FN
basic_thread(void *arg)
{
	struct cond_wait cw;
	struct event_base *base = arg;
	struct event ev;
	int i = 0;

	EVTHREAD_ALLOC_LOCK(cw.lock, 0);
	EVTHREAD_ALLOC_COND(cw.cond);
	assert(cw.lock);
	assert(cw.cond);

	evtimer_assign(&ev, base, wake_all_timeout, &cw);
	for (i = 0; i < NUM_ITERATIONS; i++) {
		struct timeval tv;
		evutil_timerclear(&tv);
		tv.tv_sec = 0;
		tv.tv_usec = 3000;

		EVLOCK_LOCK(cw.lock, 0);
		/* we need to make sure that event does not happen before
		 * we get to wait on the conditional variable */
		assert(evtimer_add(&ev, &tv) == 0);

		assert(EVTHREAD_COND_WAIT(cw.cond, cw.lock) == 0);
		EVLOCK_UNLOCK(cw.lock, 0);

		EVLOCK_LOCK(count_lock, 0);
		++count;
		EVLOCK_UNLOCK(count_lock, 0);
	}

	/* exit the loop only if all threads fired all timeouts */
	EVLOCK_LOCK(count_lock, 0);
	if (count >= NUM_THREADS * NUM_ITERATIONS)
		event_base_loopexit(base, NULL);
	EVLOCK_UNLOCK(count_lock, 0);

	EVTHREAD_FREE_LOCK(cw.lock, 0);
	EVTHREAD_FREE_COND(cw.cond);

	THREAD_RETURN();
}
Example #10
0
static THREADFN ThreadLoop(void* ptr) {
  WebPWorker* const worker = (WebPWorker*)ptr;
  int done = 0;
  while (!done) {
    pthread_mutex_lock(&worker->impl_->mutex_);
    while (worker->status_ == OK) {   // wait in idling mode
      pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_);
    }
    if (worker->status_ == WORK) {
      Execute(worker);
      worker->status_ = OK;
    } else if (worker->status_ == NOT_OK) {   // finish the worker
      done = 1;
    }
    // signal to the main thread that we're done (for Sync())
    pthread_cond_signal(&worker->impl_->condition_);
    pthread_mutex_unlock(&worker->impl_->mutex_);
  }
  return THREAD_RETURN(NULL);    // Thread is finished
}
Example #11
0
static THREADFN thread_loop(void *ptr) {    
  VP9Worker* const worker = (VP9Worker*)ptr;
  int done = 0;
  while (!done) {
    pthread_mutex_lock(&worker->mutex_);
    while (worker->status_ == OK) {   
      pthread_cond_wait(&worker->condition_, &worker->mutex_);
    }
    if (worker->status_ == WORK) {
      vp9_worker_execute(worker);
      worker->status_ = OK;
    } else if (worker->status_ == NOT_OK) {   
      done = 1;
    }
    
    pthread_cond_signal(&worker->condition_);
    pthread_mutex_unlock(&worker->mutex_);
  }
  return THREAD_RETURN(NULL);    
}
Example #12
0
static THREAD_FN
pubThread(void *arg)
{
    threadInfo  *info = (threadInfo*) arg;
    natsStatus  s     = NATS_OK;

    for (count = 0; (s == NATS_OK) && (count < total); count++)
        s = natsConnection_PublishString(info->conn, subj, txt);

    if (s == NATS_OK)
        s = natsConnection_Flush(info->conn);

    natsConnection_Close(info->conn);

    info->status = s;

    if (s != NATS_OK)
        nats_PrintLastErrorStack(stderr);

    THREAD_RETURN();
}
Example #13
0
static THREAD_FN
wait_for_condition(void *arg)
{
	struct alerted_record *rec = arg;
	int r;

	EVLOCK_LOCK(rec->cond->lock, 0);
	if (rec->delay.tv_sec || rec->delay.tv_usec) {
		r = EVTHREAD_COND_WAIT_TIMED(rec->cond->cond, rec->cond->lock,
		    &rec->delay);
	} else {
		r = EVTHREAD_COND_WAIT(rec->cond->cond, rec->cond->lock);
	}
	EVLOCK_UNLOCK(rec->cond->lock, 0);

	evutil_gettimeofday(&rec->alerted_at, NULL);
	if (r == 1)
		rec->timed_out = 1;

	THREAD_RETURN();
}
Example #14
0
thread_return_t BaseTCPServer::TCPServerLoop()
{
#ifdef WIN32
    SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL );
#endif

#ifndef WIN32
    sLog.Log( "Threading", "Starting TCPServerLoop with thread ID %d", pthread_self() );
#endif

    mMLoopRunning.Lock();

    uint32 start = GetTickCount();
    uint32 etime;
    uint32 last_time;

    while( Process() )
    {
        /* UPDATE */
        last_time = GetTickCount();
        etime = last_time - start;

        // do the stuff for thread sleeping
        if( TCPSRV_LOOP_GRANULARITY > etime )
            Sleep( TCPSRV_LOOP_GRANULARITY - etime );

        start = GetTickCount();
    }

    mMLoopRunning.Unlock();

#ifndef WIN32
    sLog.Log( "Threading", "Ending TCPServerLoop with thread ID %d", pthread_self() );
#endif

    THREAD_RETURN( NULL );
}
Example #15
0
THREAD_PROTO(acceptTask,arg){
   msocket_server_t *self = (msocket_server_t *) arg;
   if(self != 0){

      msocket_handler_t handler;
      memset(&handler,0,sizeof(handler));
      self->acceptSocket = msocket_new(self->addressFamily);

      if( (self->acceptSocket != 0) ){
         int rc;
         if(self->udpPort != 0){
            rc = msocket_listen(self->acceptSocket,MSOCKET_MODE_UDP,self->udpPort,self->udpAddr);
            if(rc<0){
               printf("*** WARNING: failed to bind to UDP port %d ***\n",self->udpPort);
               THREAD_RETURN(rc);
            }

         }
         if(self->tcpPort != 0){
            rc = msocket_listen(self->acceptSocket,MSOCKET_MODE_TCP,self->tcpPort,0);
            if(rc<0){
               printf("*** WARNING: failed to bind to TCP port %d ***\n",self->tcpPort);
               THREAD_RETURN(rc);
            }
         }
#ifndef _WIN32
         if (self->socketPath != 0)
         {
            rc = msocket_unix_listen(self->acceptSocket,self->socketPath);
            if(rc<0){
               printf("*** WARNING: failed to bind to path %s ***\n",self->socketPath);
               THREAD_RETURN(rc);
            }
         }
#endif
         while(1){
            msocket_t *child;
#ifdef MSOCKET_DEBUG
            printf("accept wait\n");
#endif
            child = msocket_accept(self->acceptSocket,0);
#ifdef MSOCKET_DEBUG
            printf("accept return\n");
#endif
            if( child == 0 ){
               break;
            }
            else{
               if(self->handlerTable.tcp_accept != 0){
                  self->handlerTable.tcp_accept(self->handlerArg, self, child);
               }
            }
         }
         msocket_delete(self->acceptSocket);
      }
   }
#ifdef MSOCKET_DEBUG
   printf("acceptThread exit\n");
#endif   
   THREAD_RETURN(0);
}
DEFINE_THREAD_ROUTINE_STACK( vp_com_server, thread_params, VP_COM_THREAD_SERVER_STACK_SIZE )
{

  vp_com_socket_t client_sockets[VP_COM_THREAD_NUM_MAX_CLIENTS];
  struct timeval tv, *ptv;

  // This thread setup connection then loop & wait for a socket event
  vp_com_server_thread_param_t* params = (vp_com_server_thread_param_t*) thread_params;

  int32_t i, rc, ncs, s, max = 0, num_server_sockets = params->num_servers, num_client_sockets = 0;
  vp_com_socket_t* server_sockets = params->servers;
  fd_set read_fs;

  vp_os_memset( client_sockets, 0, sizeof( client_sockets ));

  if(VP_FAILED(vp_com_init(params->com)))
  {
    DEBUG_PRINT_SDK("[VP_COM_SERVER] Failed to init com\n");
    vp_com_shutdown(params->com);
  }
  else if(VP_FAILED(vp_com_local_config(params->com, params->config)))
  {
    DEBUG_PRINT_SDK("[VP_COM_SERVER] Failed to configure com\n");
    vp_com_shutdown(params->com);
  }
  else if(VP_FAILED(vp_com_connect(params->com, params->connection, 1)))
  {
    DEBUG_PRINT_SDK("[VP_COM_SERVER] Failed to connect\n");
    vp_com_shutdown(params->com);
  }
  else
  {
    vp_os_mutex_lock(&server_initialisation_mutex);
    vp_os_cond_signal(&server_initialisation_wait);
    vp_os_mutex_unlock(&server_initialisation_mutex);

    server_init_not_finished = FALSE;

    for( i = 0; i < num_server_sockets; i++ )
    {
      if(VP_FAILED( vp_com_open_socket(&server_sockets[i], NULL, NULL) ))
      {
        DEBUG_PRINT_SDK("[VP_COM_SERVER] Unable to open server socket\n");
        server_sockets[i].is_disable = TRUE;
      }
      else
      {
        listen((int32_t)server_sockets[i].priv, server_sockets[i].queue_length);
      }
    }

    params->run = TRUE;

    while( params->run == TRUE )
    {
      if( params->timer_enable == FALSE || ( params->wait_sec == 0 && params->wait_usec == 0 ) )
      {
        ptv = NULL;
      }
      else
      {
        tv.tv_sec   = params->wait_sec;
        tv.tv_usec  = params->wait_usec;
        ptv         = &tv;
      }

      FD_ZERO(&read_fs);
      max = vp_com_fill_read_fs( &server_sockets[0], num_server_sockets, 0, &read_fs );
      max = vp_com_fill_read_fs( &client_sockets[0], num_client_sockets, max, &read_fs );

      rc = select( max + 1, &read_fs, NULL, NULL, ptv );
      if( rc == -1 && ( errno == EINTR || errno == EAGAIN ) )
        continue;

      if( rc == 0 )
      {
        DEBUG_PRINT_SDK("[VP_COM_SERVER] select timeout\n");

        vp_com_close_client_sockets(&client_sockets[0], num_client_sockets);
        num_client_sockets = 0;

        params->timer_enable  = FALSE;
        vp_os_memset( client_sockets, 0, sizeof( client_sockets ));
      }

      for( i = 0; i < num_server_sockets && rc != 0; i++ )
      {
        s = (int32_t) server_sockets[i].priv;

        if( ( !server_sockets[i].is_disable ) && FD_ISSET( s, &read_fs) )
        {
          rc --;

          // Recycle previously released sockets
          for( ncs = 0; ncs < num_client_sockets && client_sockets[ncs].priv != NULL; ncs++ );

          if( ncs < VP_COM_THREAD_NUM_MAX_CLIENTS)
          {
            if( VP_SUCCEEDED(vp_com_client_open_socket(&server_sockets[i], &client_sockets[ncs])) && ( ncs == num_client_sockets ) )
              num_client_sockets ++;
          }
        }
      }

      for( i = 0; i < num_client_sockets && rc != 0; i++ )
      {
        s = (int32_t) client_sockets[i].priv;
        if( ( !client_sockets[i].is_disable ) && FD_ISSET( s, &read_fs) )
        {
          rc--;

          vp_com_client_receive( &client_sockets[i] );
        }
      }
    }

    for( i = 0; i < num_server_sockets; i++ )
    {
      vp_com_close_socket(&server_sockets[i]);
    }
  }

  vp_com_disconnect(params->com);
  vp_com_shutdown(params->com);


  THREAD_RETURN( 0 );
}
Example #17
0
static DECLARE_THREAD_FUNCTION(GTimerThreadHandler, arg) {
	GTimer			*pt;
	systemticks_t	tm;
	systemticks_t	nxtTimeout;
	systemticks_t	lastTime;
	GTimerFunction	fn;
	void			*param;
	(void)			arg;

	nxtTimeout = TIME_INFINITE;
	lastTime = 0;
	while(1) {
		/* Wait for work to do. */
		gfxYield();					// Give someone else a go no matter how busy we are
		gfxSemWait(&waitsem, nxtTimeout);
		
	restartTimerChecks:
	
		// Our reference time
		tm = gfxSystemTicks();
		nxtTimeout = TIME_INFINITE;
		
		/* We need to obtain the mutex */
		gfxMutexEnter(&mutex);

		if (pTimerHead) {
			pt = pTimerHead;
			do {
				// Do we have something to do for this timer?
				if ((pt->flags & GTIMER_FLG_JABBED) || (!(pt->flags & GTIMER_FLG_INFINITE) && TimeIsWithin(pt->when, lastTime, tm))) {
				
					// Is this timer periodic?
					if ((pt->flags & GTIMER_FLG_PERIODIC) && pt->period != TIME_IMMEDIATE) {
						// Yes - Update ready for the next period
						if (!(pt->flags & GTIMER_FLG_INFINITE)) {
							// We may have skipped a period.
							// We use this complicated formulae rather than a loop
							//	because the gcc compiler stuffs up the loop so that it
							//	either loops forever or doesn't get executed at all.
							pt->when += ((tm + pt->period - pt->when) / pt->period) * pt->period;
						}

						// We are definitely no longer jabbed
						pt->flags &= ~GTIMER_FLG_JABBED;
						
					} else {
						// No - get us off the timers list
						if (pt->next == pt)
							pTimerHead = 0;
						else {
							pt->next->prev = pt->prev;
							pt->prev->next = pt->next;
							if (pTimerHead == pt)
								pTimerHead = pt->next;
						}
						pt->flags = 0;
					}
					
					// Call the callback function
					fn = pt->fn;
					param = pt->param;
					gfxMutexExit(&mutex);
					fn(param);
					
					// We no longer hold the mutex, the callback function may have taken a while
					// and our list may have been altered so start again!
					goto restartTimerChecks;
				}
				
				// Find when we next need to wake up
				if (!(pt->flags & GTIMER_FLG_INFINITE) && pt->when - tm < nxtTimeout)
					nxtTimeout = (pt->when - tm)/ticks2ms;
				pt = pt->next;
			} while(pt != pTimerHead);
		}

		// Ready for the next loop
		lastTime = tm;
		gfxMutexExit(&mutex);
	}
	THREAD_RETURN(0);
}
DEFINE_THREAD_ROUTINE(academy_upload, data)
{
	char *directoryList = NULL;
	char *fileList = NULL;
	char dirname[ACADEMY_MAX_FILENAME];
	_ftp_t *academy_ftp = NULL;
	_ftp_status academy_status;
	char *ptr = NULL;
	academy_upload_t *academy = (academy_upload_t *)data;

	printf("Start thread %s\n", __FUNCTION__);

	while( academy_upload_started && !ardrone_tool_exit() )
	{
		vp_os_mutex_lock(&academy->mutex);
		vp_os_memset(&academy->user, 0, sizeof(academy_user_t));
		academy->callback = &academy_upload_private_callback;
		academy->connected = FALSE;
		academy_upload_resetState(academy);
		vp_os_cond_wait(&academy->cond);
		vp_os_mutex_unlock(&academy->mutex);

		while(academy_upload_started && academy->connected)
		{
			academy_status = FTP_FAIL;
			academy_upload_nextState(academy);

			switch(academy->state.state)
			{
				case ACADEMY_STATE_CONNECTION:
					{
						struct dirent *dirent = NULL;
						DIR *dir = NULL;
						academy_status = FTP_FAIL;

						// Check if flight_* directory exist in local dir
						if((dir = opendir(flight_dir)) != NULL)
						{
							struct stat statbuf;
							while(FTP_FAILED(academy_status) && (dirent = readdir(dir)) != NULL)
							{
								if((strncmp(dirent->d_name, "flight_", strlen("flight_")) == 0))
								{
									char local_dir[ACADEMY_MAX_FILENAME];
									sprintf(dirname, "%s", dirent->d_name);
									sprintf(local_dir, "%s/%s", flight_dir, dirname);
									if((stat(local_dir, &statbuf) == 0) && S_ISDIR(statbuf.st_mode))
										academy_status = FTP_SUCCESS;
								}
							}
                            closedir(dir);
						}

						if(FTP_SUCCEDED(academy_status))
						{
							if(academy_ftp == NULL)
								academy_ftp = ftpConnectFromName(ACADEMY_SERVERNAME, ACADEMY_PORT, academy->user.username, academy->user.password, &academy_status);
						}
					}
					break;

				case ACADEMY_STATE_PREPARE_PROCESS:
					academy_status = ftpCd(academy_ftp, "/Uploaded");
					if(FTP_FAILED(academy_status))
					{
						ftpMkdir(academy_ftp, "/Uploaded");
						academy_status = ftpCd(academy_ftp, "/Uploaded");
					}

					if(FTP_SUCCEDED(academy_status))
					{
						academy_status = ftpList(academy_ftp, &directoryList, NULL);
						if(FTP_SUCCEDED(academy_status))
						{
							bool_t found = FALSE;
							char *next_dir = NULL;

							while(!found && (ptr = academy_get_next_item_with_prefix(directoryList, &next_dir, "flight_", TRUE)))
							{
								if(strcmp(ptr, dirname) == 0)
								{
									found = TRUE;
									academy_upload_setState(academy, ACADEMY_STATE_FINISH_PROCESS);
								}
							}

							if(directoryList != NULL)
							{
								vp_os_free(directoryList);
								directoryList = NULL;
							}
						}
					}
					break;

				case ACADEMY_STATE_PROCESS:
					academy_status = ftpCd(academy_ftp, "/Uploading");
					if(FTP_FAILED(academy_status))
					{
						ftpMkdir(academy_ftp, "/Uploading");
						academy_status = ftpCd(academy_ftp, "/Uploading");
					}

					if(FTP_SUCCEDED(academy_status))
					{
						ftpMkdir(academy_ftp, dirname);
						academy_status = ftpCd(academy_ftp, dirname);
						if(FTP_SUCCEDED(academy_status))
						{
							char local_dir[ACADEMY_MAX_FILENAME];
							struct dirent *dirent = NULL;
							DIR *dir = NULL;

							sprintf(local_dir, "%s/%s", flight_dir, dirname);
							if((dir = opendir(local_dir)) != NULL)
							{
								char local_filename[ACADEMY_MAX_FILENAME];
								struct stat statbuf;
								while(FTP_SUCCEDED(academy_status) && ((dirent = readdir(dir)) != NULL))
								{
									if((strncmp(dirent->d_name, "picture_", strlen("picture_")) == 0) || (strncmp(dirent->d_name, "userbox_", strlen("userbox_")) == 0))
									{
										sprintf(local_filename, "%s/%s", local_dir, dirent->d_name);
										if((stat(local_filename, &statbuf) == 0) && !S_ISDIR(statbuf.st_mode))
										{
											PA_DEBUG("Put %s from local directory to server...", dirent->d_name);
											academy_status = ftpPut(academy_ftp, local_filename, dirent->d_name, 1, NULL);
											if(FTP_SUCCEDED(academy_status))
												PA_DEBUG("OK\n");
											else
												PA_DEBUG("ERROR\n");
										}
									}
								}
                                
                                closedir(dir);
							}
						}
					}
					break;

				case ACADEMY_STATE_FINISH_PROCESS:
					{
						char local_dir[ACADEMY_MAX_FILENAME];
						char src[ACADEMY_MAX_FILENAME];
						char dest[ACADEMY_MAX_FILENAME];
						sprintf(src, "/Uploading/%s", dirname);
						sprintf(dest, "/Uploaded/%s", dirname);
						academy_status = ftpRename(academy_ftp, src, dest);

						// Penser à supprimer le fichier local
						academy_status = FTP_FAIL;
						sprintf(local_dir, "%s/%s", flight_dir, dirname);
						if(!ftw(local_dir, &academy_remove, 1))
						{
							rmdir(local_dir);
							academy_status = FTP_SUCCESS;
						}
					}
					break;

				case ACADEMY_STATE_DISCONNECTION:
					if(academy_ftp != NULL)
						ftpClose(&academy_ftp);
					academy_status = FTP_SUCCESS;
					break;

				default:
					// Nothing to do
					break;
			}

			if(FTP_SUCCEDED(academy_status))
			{
				PA_DEBUG("continue state from %d to %d\n", academy->state.state, (academy->state.state + 1) % ACADEMY_STATE_MAX);
				academy_upload_stateOK(academy);
			}
			else
			{
				PA_DEBUG("stop\n");
				academy_upload_stateERROR(academy);

				if(fileList != NULL)
				{
					vp_os_free(fileList);
					fileList = NULL;
				}

				if(academy_ftp)
					ftpClose(&academy_ftp);

				vp_os_delay(1000);
			}
		}

		if(fileList != NULL)
		{
			vp_os_free(fileList);
			fileList = NULL;
		}

		if(academy_ftp)
			ftpClose(&academy_ftp);
	} // while

	THREAD_RETURN(C_OK);
}
DEFINE_THREAD_ROUTINE( ardrone_control, nomParams )
{
	C_RESULT res_wait_navdata = C_OK;
	C_RESULT res = C_OK;
	uint32_t retry, current_ardrone_state;
	int32_t next_index_in_queue;
	ardrone_control_event_ptr_t  current_event;
	
	retry = 0;
	current_event = NULL;
	
	DEBUG_PRINT_SDK("Thread control in progress...\n");
	control_socket.is_disable = TRUE;
	
	ardrone_control_connect_to_drone();

	while( bContinue 
          && !ardrone_tool_exit() )
	{
		vp_os_mutex_lock(&control_mutex);
		control_waited = TRUE;

		/* Wait for new navdata to be received. */
		res_wait_navdata = vp_os_cond_timed_wait(&control_cond, 1000);
		vp_os_mutex_unlock(&control_mutex);

		/*
		 * In case of timeout on the navdata, we assume that there was a problem
		 * with the Wifi connection.
		 * It is then safer to close and reopen the control socket (TCP 5559) since
		 * some OS might stop giving data but not signal any disconnection.
		 */
		if(VP_FAILED(res_wait_navdata))
		{
			DEBUG_PRINT_SDK("Timeout while waiting for new navdata.\n");
			if(!control_socket.is_disable)
				control_socket.is_disable = TRUE;
		}
			
		if(control_socket.is_disable)
		{
			ardrone_control_connect_to_drone();
		}
		
		if(VP_SUCCEEDED(res_wait_navdata) && (!control_socket.is_disable))
		{
			vp_os_mutex_lock(&control_mutex);
			current_ardrone_state = ardrone_state;
			control_waited = FALSE;
			vp_os_mutex_unlock(&control_mutex);
			
			if( ardrone_tool_exit() ) // Test if we received a signal because we are quitting the application
				THREAD_RETURN( res );
			
 			if( current_event == NULL )
			{
				vp_os_mutex_lock(&event_queue_mutex);
				next_index_in_queue = (end_index_in_queue + 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
				
				if( next_index_in_queue != start_index_in_queue )
				{ // There's an event to process
					current_event = ardrone_control_event_queue[next_index_in_queue];
					if( current_event != NULL )
					{
						if( current_event->ardrone_control_event_start != NULL )
						{
							current_event->ardrone_control_event_start( current_event );
						}
					}
					end_index_in_queue = next_index_in_queue;
					
					retry = 0;
				}
				
				vp_os_mutex_unlock(&event_queue_mutex);
			}
			
			if( current_event != NULL )
			{
				switch( current_event->event )
				{
					case ARDRONE_UPDATE_CONTROL_MODE:
						res = ardrone_control_soft_update_run( current_ardrone_state, (ardrone_control_soft_update_event_t*) current_event );
						break;
						
					case PIC_UPDATE_CONTROL_MODE:
						res = ardrone_control_soft_update_run( current_ardrone_state, (ardrone_control_soft_update_event_t*) current_event );
						break;
						
					case LOGS_GET_CONTROL_MODE:
						break;
						
					case CFG_GET_CONTROL_MODE:
					case CUSTOM_CFG_GET_CONTROL_MODE: /* multiconfiguration support */
						res = ardrone_control_configuration_run( current_ardrone_state, (ardrone_control_configuration_event_t*) current_event );
						break;
						
					case ACK_CONTROL_MODE:
						res = ardrone_control_ack_run( current_ardrone_state, (ardrone_control_ack_event_t *) current_event);
						break;
						
					default:
						break;
				}
				
				if( VP_FAILED(res) )
				{
					retry ++;
					if( retry > current_event->num_retries)
						current_event->status = ARDRONE_CONTROL_EVENT_FINISH_FAILURE;
				}
				else
				{
					retry = 0;
				}
				
				if( current_event->status & ARDRONE_CONTROL_EVENT_FINISH )
				{
 					if( current_event->ardrone_control_event_end != NULL )
						current_event->ardrone_control_event_end( current_event );
					
 					/* Make the thread read a new event on the next loop iteration */
					current_event = NULL;
				}
				else
				{
					/* Not changing 'current_event' makes the loop process the same
					 * event when the next navdata packet arrives. */
				}
			}
		}
  }// while

  /* Stephane : Bug fix - mutexes were previously detroyed by another thread,
  which made ardrone_control crash.*/
	  vp_os_mutex_destroy(&event_queue_mutex);
	  vp_os_cond_destroy(&control_cond);
	  vp_os_mutex_destroy(&control_mutex);

  vp_com_close(COM_CONTROL(), &control_socket);

  THREAD_RETURN( res );
}