Face one of the refactoring! callbacks on http requests get now called by the main thread. So absolutely zero thread-safety has to be taken care of, outside of HTTPManager and its requests.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13503 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
unitraxx 2013-08-18 22:22:00 +00:00
parent 17b9479fce
commit 37f3f55da8
9 changed files with 82 additions and 190 deletions

View File

@ -31,7 +31,7 @@
#include "modes/world.hpp"
#include "network/protocol_manager.hpp"
#include "network/network_world.hpp"
#include "online/database_polling.hpp"
#include "online/http_manager.hpp"
#include "race/race_manager.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/profiler.hpp"
@ -155,7 +155,7 @@ void MainLoop::run()
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F);
DatabasePolling::getInstance()->update();
Online::HTTPManager::get()->update(dt);
PROFILER_POP_CPU_MARKER();
PROFILER_SYNC_FRAME();

View File

@ -374,6 +374,11 @@ namespace Online{
//FIXME
}
}
// ============================================================================
void CurrentUser::requestPoll()
{
//FIXME
}
// ============================================================================

View File

@ -173,6 +173,8 @@ namespace Online{
}
const std::string getToken() const { return m_token.getAtomic(); }
void requestPoll();
}; // class CurrentUser
} // namespace Online

View File

@ -1,99 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/database_polling.hpp"
#include <string>
#include <irrString.h>
#include <assert.h>
#include "utils/translation.hpp"
#include "utils/time.hpp"
#include "online/current_user.hpp"
#define MENU_POLLING_INTERVAL 5.0f
#define RACE_POLLING_INTERVAL 10.0f
namespace Online{
static DatabasePolling * database_polling_singleton(NULL);
DatabasePolling* DatabasePolling::get()
{
if (database_polling_singleton == NULL)
database_polling_singleton = new DatabasePolling();
return database_polling_singleton;
}
void DatabasePolling::deallocate()
{
delete database_polling_singleton;
database_polling_singleton = NULL;
} // deallocate
// ============================================================================
DatabasePolling::DatabasePolling(){
m_time_since_poll = 0.0f;
}
DatabasePolling::~DatabasePolling(){
}
void DatabasePolling::generateNewPollRequest(){
}
void DatabasePolling::addResult(Online::Request *request)
{
assert(request->isDone());
m_result_queue.lock();
m_result_queue.getData().push(request);
m_result_queue.unlock();
}
DatabasePolling::PollRequest * DatabasePolling::popResult()
{
PollRequest * request = NULL;
m_result_queue.lock();
if(!m_result_queue.getData().empty())
{
request = (PollRequest*) m_result_queue.getData().front();
m_result_queue.getData().pop();
}
m_result_queue.unlock();
return request;
}
void DatabasePolling::update(float dt){
if(!CurrentUser::get()->isRegisteredUser())
return;
PollRequest * request = popResult();
if(request != NULL)
request->onPollFetch();
m_time_since_poll += dt;
float interval = MENU_POLLING_INTERVAL;
if(m_time_since_poll > interval)
{
m_time_since_poll = 0;
generateNewPollRequest();
}
}
} // namespace Online

View File

@ -1,78 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_DATABASE_POLLING_HPP
#define HEADER_DATABASE_POLLING_HPP
#include "utils/types.hpp"
#include "utils/synchronised.hpp"
#include "http_manager.hpp"
#include <queue>
namespace Online {
/**
* \brief
* \ingroup online
*/
class DatabasePolling
{
class PollRequest : public XMLRequest
{
void callback ()
{
DatabasePolling::get()->addResult(this);
}
public:
PollRequest() : XMLRequest() {}
void onPollFetch() = 0;
};
private:
DatabasePolling();
~DatabasePolling();
float m_time_since_poll;
/** The list of pointers to all requests that are handled and needed to be put in the queue */
Synchronised< std::queue<Online::Request*> > m_result_queue;
void addResult(Online::Request *request);
PollRequest * popResult();
void DatabasePolling::generateNewPollRequest();
public:
// Singleton
static DatabasePolling* get();
static void deallocate();
void update(float dt);
}; // class DatabasePolling
} // namespace Online
#endif
/*EOF*/

View File

@ -20,6 +20,8 @@
#include "online/http_manager.hpp"
#include "online/current_user.hpp"
#include <iostream>
#include <stdio.h>
#include <memory.h>
@ -41,7 +43,11 @@
# include <unistd.h>
#endif
using namespace Online;
namespace Online{
#define MENU_POLLING_INTERVAL 5.0f
#define RACE_POLLING_INTERVAL 10.0f
static HTTPManager * http_singleton = NULL;
@ -71,6 +77,7 @@ namespace Online{
curl_global_init(CURL_GLOBAL_DEFAULT);
pthread_cond_init(&m_cond_request, NULL);
m_abort.setAtomic(false);
m_time_since_poll = 0.0f;
}
// ============================================================================
@ -197,11 +204,8 @@ namespace Online{
me->m_request_queue.getData().pop();
me->m_request_queue.unlock();
me->m_current_request->execute();
if(me->m_current_request->manageMemory())
{
delete me->m_current_request;
me->m_current_request = NULL;
}
me->m_current_request->callback();
me->addResult(me->m_current_request);
me->m_request_queue.lock();
} // while
@ -219,6 +223,55 @@ namespace Online{
pthread_exit(NULL);
return 0;
} // mainLoop
void HTTPManager::addResult(Online::Request *request)
{
assert(request->isBusy());
m_result_queue.lock();
m_result_queue.getData().push(request);
m_result_queue.unlock();
}
void HTTPManager::handleResultQueue()
{
Request * request = NULL;
m_result_queue.lock();
if(!m_result_queue.getData().empty())
{
request = m_result_queue.getData().front();
m_result_queue.getData().pop();
}
m_result_queue.unlock();
if(request != NULL)
{
request->callback();
if(request->manageMemory())
{
delete request;
request = NULL;
}
else
request->setDone();
}
}
void HTTPManager::update(float dt){
handleResultQueue();
//Database polling starts here, only needed for registered users
if(!CurrentUser::get()->isRegisteredUser())
return;
m_time_since_poll += dt;
float interval = MENU_POLLING_INTERVAL;
if(m_time_since_poll > interval)
{
m_time_since_poll = 0;
CurrentUser::get()->requestPoll();
}
}
} // namespace Online

View File

@ -48,7 +48,7 @@ namespace Online{
{
protected:
/** Ment for networking threads */
float m_time_since_poll;
/** The current requested being worked on. */
Online::Request * m_current_request;
@ -70,6 +70,11 @@ namespace Online{
>
> m_request_queue;
Synchronised< std::queue<Online::Request*> > m_result_queue;
void addResult(Online::Request *request);
void handleResultQueue();
static void *mainLoop(void *obj);
void startNetworkThread();
@ -93,6 +98,7 @@ namespace Online{
void stopNetworkThread();
bool getAbort(){ return m_abort.getAtomic(); };
void update(float dt);
}; //class HTTPManager
} // namespace Online

View File

@ -53,7 +53,6 @@ namespace Online{
void Request::afterOperation()
{
m_state.setAtomic(S_DONE);
}
// =========================================================================================
@ -149,7 +148,6 @@ namespace Online{
else
setProgress(-1.0f);
curl_easy_cleanup(m_curl_session);
callback();
Request::afterOperation();
}

View File

@ -30,7 +30,7 @@
#include <curl/curl.h>
#include <assert.h>
#include <string>
network_world
namespace Online{
/**
@ -101,6 +101,9 @@ namespace Online{
/** Returns if this request is done. */
bool isDone() const { return m_state.getAtomic() == S_DONE; }
// ------------------------------------------------------------------------
/** Should only be called by the manager */
void setDone() { m_state.setAtomic(S_DONE); }
// ------------------------------------------------------------------------
/** Returns if this request is being prepared. */
bool isPreparing() const { return m_state.getAtomic() == S_PREPARING; }
// ------------------------------------------------------------------------
@ -113,6 +116,9 @@ namespace Online{
/** Virtual method to check if a request has initialized all needed members to a valid value. */
virtual bool isAllowedToAdd() const { return isPreparing(); }
/** Executed when a request has finished. */
virtual void callback() {}
/** This class is used by the priority queue to sort requests by priority.
*/
class Compare
@ -150,8 +156,7 @@ namespace Online{
virtual void prepareOperation() OVERRIDE;
virtual void operation() OVERRIDE;
virtual void afterOperation() OVERRIDE;
/** Executed when a request has finished. */
virtual void callback() {}
static int progressDownload( void *clientp,
double dltotal,