Added proper aborting of curl download threads.
Print warning and progress reports only with verbosity 3 or above, all addons messages now start with [addons]. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7503 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
d8b04b2338
commit
6eddb2baf9
@ -104,7 +104,7 @@ void AddonsManager::initOnline(const XMLNode *xml)
|
||||
if(file_manager->fileExists(full_path))
|
||||
{
|
||||
if(UserConfigParams::m_verbosity>=3)
|
||||
printf("Removing cached icon '%s'.\n",
|
||||
printf("[addons] Removing cached icon '%s'.\n",
|
||||
addon.getIconBasename().c_str());
|
||||
file_manager->removeFile(full_path);
|
||||
}
|
||||
@ -124,9 +124,9 @@ void AddonsManager::initOnline(const XMLNode *xml)
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Found invalid node '%s' while downloading addons.\n",
|
||||
"[addons] Found invalid node '%s' while downloading addons.\n",
|
||||
node->getName().c_str());
|
||||
fprintf(stderr, "Ignored.\n");
|
||||
fprintf(stderr, "[addons] Ignored.\n");
|
||||
}
|
||||
} // for i<xml->getNumNodes
|
||||
delete xml;
|
||||
@ -205,7 +205,7 @@ void *AddonsManager::downloadIcons(void *obj)
|
||||
for(unsigned int i=0; i<me->m_addons_list.getData().size(); i++)
|
||||
{
|
||||
if(!me->m_addons_list.getData()[i].iconReady())
|
||||
printf("No icon for '%s'.\n",
|
||||
printf("[addons] No icon for '%s'.\n",
|
||||
me->m_addons_list.getData()[i].getId().c_str());
|
||||
}
|
||||
me->saveInstalled();
|
||||
@ -230,7 +230,7 @@ bool AddonsManager::onlineReady()
|
||||
void AddonsManager::loadInstalledAddons()
|
||||
{
|
||||
/* checking for installed addons */
|
||||
std::cout << "[Addons] Loading an xml file for installed addons: ";
|
||||
std::cout << "[addons] Loading an xml file for installed addons: ";
|
||||
std::cout << m_file_installed << std::endl;
|
||||
const XMLNode *xml = file_manager->createXMLTree(m_file_installed);
|
||||
if(!xml)
|
||||
|
@ -54,7 +54,7 @@ NetworkHttp *network_http;
|
||||
* This separate thread is running in NetworkHttp::mainLoop, and is being
|
||||
* waken up if a command is issued (e.g. using downloadFileAsynchronous).
|
||||
*/
|
||||
NetworkHttp::NetworkHttp() : m_news(""), m_progress(-1.0f)
|
||||
NetworkHttp::NetworkHttp() : m_news(""), m_progress(-1.0f), m_abort(false)
|
||||
{
|
||||
pthread_mutex_init(&m_mutex_command, NULL);
|
||||
pthread_cond_init(&m_cond_command, NULL);
|
||||
@ -133,15 +133,24 @@ void *NetworkHttp::mainLoop(void *obj)
|
||||
*/
|
||||
NetworkHttp::~NetworkHttp()
|
||||
{
|
||||
// if a download should be active (which means it was cancelled by the
|
||||
// user, in which case it will still be ongoing in the background)
|
||||
// we can't get the mutex, and would have to wait for a timeout,
|
||||
// and we couldn't finish STK. This way we request an abort of
|
||||
// a download, which mean we can get the mutex and ask the service
|
||||
// thread here to cancel properly.
|
||||
cancelDownload();
|
||||
pthread_mutex_lock(&m_mutex_command);
|
||||
{
|
||||
m_command=HC_QUIT;
|
||||
pthread_cond_signal(&m_cond_command);
|
||||
}
|
||||
pthread_mutex_unlock(&m_mutex_command);
|
||||
printf("[addons] Mutex unlocked.\n");
|
||||
|
||||
void *result;
|
||||
pthread_join(m_thread_id, &result);
|
||||
printf("[addons] Network thread joined.\n");
|
||||
|
||||
pthread_mutex_destroy(&m_mutex_command);
|
||||
pthread_cond_destroy(&m_cond_command);
|
||||
@ -213,6 +222,7 @@ size_t NetworkHttp::writeStr(char ptr [], size_t size, size_t nb_char,
|
||||
|
||||
std::string NetworkHttp::downloadToStrInternal(std::string url)
|
||||
{
|
||||
m_abort.set(false);
|
||||
CURL *session = curl_easy_init();
|
||||
|
||||
std::string full_url = (std::string)UserConfigParams::m_server_addons
|
||||
@ -244,7 +254,7 @@ bool NetworkHttp::downloadFileInternal(const std::string &file,
|
||||
bool is_asynchron)
|
||||
{
|
||||
if(UserConfigParams::m_verbosity>=3)
|
||||
printf("Downloading %s\n", file.c_str());
|
||||
printf("[addons] Downloading %s\n", file.c_str());
|
||||
CURL *session = curl_easy_init();
|
||||
std::string full_url = (std::string)UserConfigParams::m_server_addons
|
||||
+ "/" + file;
|
||||
@ -277,6 +287,18 @@ bool NetworkHttp::downloadFileInternal(const std::string &file,
|
||||
return success==CURLE_OK;
|
||||
} // downloadFileInternal
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Signals to the progress function to request any ongoing download to be
|
||||
* cancelled. This function can also be called if there is actually no
|
||||
* download atm. The function progressDownload checks m_abort and will
|
||||
* return a non-zero value which causes libcurl to abort. */
|
||||
void NetworkHttp::cancelDownload()
|
||||
{
|
||||
if(UserConfigParams::m_verbosity>=3)
|
||||
printf("[addons] Requesting cancellation of download.\n");
|
||||
m_abort.set(true);
|
||||
} // cancelDownload
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** External interface to download a file synchronously, i.e. it will only
|
||||
* return once the download is complete.
|
||||
@ -288,6 +310,9 @@ bool NetworkHttp::downloadFileSynchron(const std::string &file,
|
||||
const std::string &save)
|
||||
{
|
||||
const std::string &save_filename = (save!="") ? save : file;
|
||||
if(UserConfigParams::m_verbosity>=3)
|
||||
printf("[addons] Download synchron '%s' as '%s'.\n",
|
||||
file.c_str(), save_filename.c_str());
|
||||
|
||||
return downloadFileInternal(file, save_filename,
|
||||
/*is_asynchron*/false);
|
||||
@ -308,6 +333,9 @@ void NetworkHttp::downloadFileAsynchron(const std::string &file,
|
||||
m_file = file;
|
||||
m_save_filename = (save!="") ? save : file;
|
||||
|
||||
if(UserConfigParams::m_verbosity>=3)
|
||||
printf("[addons] Download asynchron '%s' as '%s'.\n",
|
||||
file.c_str(), m_save_filename.c_str());
|
||||
// Wake up the network http thread
|
||||
pthread_mutex_lock(&m_mutex_command);
|
||||
{
|
||||
@ -329,6 +357,14 @@ int NetworkHttp::progressDownload(void *clientp,
|
||||
double download_total, double download_now,
|
||||
double upload_total, double upload_now)
|
||||
{
|
||||
// Check if we are asked to abort the download. If so, signal this
|
||||
// back to libcurl by returning a non-zero status.
|
||||
if(network_http->m_abort.get())
|
||||
{
|
||||
if(UserConfigParams::m_verbosity>=3)
|
||||
printf("[addons] Aborting download in progress.\n");
|
||||
return 1;
|
||||
}
|
||||
float f;
|
||||
if(download_now < download_total)
|
||||
{
|
||||
|
@ -64,6 +64,9 @@ private:
|
||||
* this value only becomes 1.0f, if the download is completed.*/
|
||||
Synchronised<float> m_progress;
|
||||
|
||||
/** Signal an abort in case that a download is still happening. */
|
||||
Synchronised<bool> m_abort;
|
||||
|
||||
/** Thread id of the thread running in this object. */
|
||||
pthread_t m_thread_id;
|
||||
|
||||
@ -91,7 +94,7 @@ public:
|
||||
const std::string
|
||||
getNewsMessage() const;
|
||||
float getProgress() const;
|
||||
|
||||
void cancelDownload();
|
||||
}; // NetworkHttp
|
||||
|
||||
extern NetworkHttp *network_http;
|
||||
|
@ -75,7 +75,7 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
for(unsigned int i=0; i<zip_file_list->getFileCount(); i++)
|
||||
{
|
||||
const std::string current_file=zip_file_list->getFileName(i).c_str();
|
||||
std::cout << current_file << std::endl;
|
||||
printf("[addons] Unzipping file '%s'.\n", current_file.c_str());
|
||||
if(zip_file_list->isDirectory(i)) continue;
|
||||
if(current_file[0]=='.') continue;
|
||||
const std::string base = StringUtils::getBasename(current_file);
|
||||
@ -84,8 +84,8 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
file_system->createAndOpenFile(current_file.c_str());
|
||||
if(!src_file)
|
||||
{
|
||||
printf("Can't read file '%s'.\n", current_file.c_str());
|
||||
printf("This is ignored, but the addon might not work.\n");
|
||||
printf("[addons] Can't read file '%s'.\n", current_file.c_str());
|
||||
printf("[addons] This is ignored, but the addon might not work.\n");
|
||||
error = true;
|
||||
continue;
|
||||
}
|
||||
@ -94,19 +94,19 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
file_system->createAndWriteFile((to+"/"+base).c_str());
|
||||
if(dst_file == NULL)
|
||||
{
|
||||
printf("Couldn't create the file '%s'.\n",
|
||||
printf("[addons] Couldn't create the file '%s'.\n",
|
||||
(to+"/"+current_file).c_str());
|
||||
printf("The directory might not exist.\n");
|
||||
printf("This is ignored, but the addon might not work.\n");
|
||||
printf("[addons] The directory might not exist.\n");
|
||||
printf("[addons] This is ignored, but the addon might not work.\n");
|
||||
error = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IFileSystem_copyFileToFile(dst_file, src_file) < 0)
|
||||
{
|
||||
printf("Could not copy '%s' from archive '%s'.\n",
|
||||
printf("[addons] Could not copy '%s' from archive '%s'.\n",
|
||||
current_file.c_str(), from.c_str());
|
||||
printf("This is ignored, but the addon might not work.\n");
|
||||
printf("[addons] This is ignored, but the addon might not work.\n");
|
||||
error = true;
|
||||
}
|
||||
dst_file->drop();
|
||||
|
@ -64,13 +64,11 @@ void AddonsScreen::init()
|
||||
Screen::init();
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->setDeactivated();
|
||||
|
||||
std::cout << "[Addons] Using directory <" + file_manager->getAddonsDir()
|
||||
std::cout << "[addons] Using directory <" + file_manager->getAddonsDir()
|
||||
<< ">\n";
|
||||
GUIEngine::ListWidget* w_list =
|
||||
getWidget<GUIEngine::ListWidget>("list_addons");
|
||||
w_list->setIcons(m_icon_bank);
|
||||
//w_list->clear();
|
||||
std::cout << "icon bank" << std::endl;
|
||||
|
||||
getWidget<GUIEngine::LabelWidget>("update_status")
|
||||
->setText(_("Updating the list..."));
|
||||
|
@ -83,6 +83,7 @@ GUIEngine::EventPropagation
|
||||
{
|
||||
if(event_source == "cancel")
|
||||
{
|
||||
network_http->cancelDownload();
|
||||
dismiss();
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user