diff --git a/source/src/Makefile b/source/src/Makefile index 289f532b..09898b94 100644 --- a/source/src/Makefile +++ b/source/src/Makefile @@ -115,7 +115,7 @@ SERVER_INCLUDES= -DSTANDALONE $(INCLUDES) -I../include SERVER_LIBS= -L../lib -lzdll -lenet -lws2_32 -lwinmm else SERVER_INCLUDES= -DSTANDALONE $(INCLUDES) -SERVER_LIBS= -L../enet/.libs -lenet -lz -lpthread +SERVER_LIBS= -L../enet/.libs -lenet -lz -lpthread -lrt endif SERVER_OBJS= \ diff --git a/source/src/autodownload.cpp b/source/src/autodownload.cpp index 5d1562c6..21ef9a90 100644 --- a/source/src/autodownload.cpp +++ b/source/src/autodownload.cpp @@ -53,13 +53,16 @@ COMMAND(addpckserver, "ss"); void getpckserver() // return a table of all package servers with four columns { - sem_pckservers.wait(); vector res; - loopv(pckservers) cvecprintf(res, "\"%s\" %d %d %d\n", pckservers[i]->host, pckservers[i]->priority, pckservers[i]->ping, pckservers[i]->resolved); + if(sem_pckservers.timedwait(1000)) cvecprintf(res, "\"serverlist is busy, try again later\" "); // single-word return value signals an error + else + { + loopv(pckservers) cvecprintf(res, "\"%s\" %d %d %d\n", pckservers[i]->host, pckservers[i]->priority, pckservers[i]->ping, pckservers[i]->resolved); + sem_pckservers.post(); + } if(res.length()) res.last() = '\0'; else res.add('\0'); result(res.getbuf()); - sem_pckservers.post(); } COMMAND(getpckserver, ""); @@ -430,7 +433,7 @@ int downloadpackages(bool loadscr) // get all pending packages httpget h; canceldownloads = false; progress_of = loadscr ? pendingpackages.length() : -1; - if(sem_pckservers.trywait()) + if(sem_pckservers.timedwait(1000)) { // can't lock the server list -> this means, the server ping threads have not finished yet if(pendingpackages.length()) conoutf("\f3failed to download packages: still pinging the servers..."); return 0; diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 9fbd49c8..c2e4405f 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -543,6 +543,11 @@ int sl_semaphore::trywait() return SDL_SemTryWait((SDL_sem *) data); } +int sl_semaphore::timedwait(int howlongmillis) +{ + return SDL_SemWaitTimeout((SDL_sem *) data, howlongmillis); +} + int sl_semaphore::getvalue() { return SDL_SemValue((SDL_sem *) data); @@ -579,6 +584,20 @@ int sl_semaphore::trywait() return sem_trywait((sem_t *) data); } +int sl_semaphore::timedwait(int howlongmillis) +{ + struct timespec t; + if(clock_gettime(CLOCK_REALTIME, &t)) + { + (*errorcount)++; + return sem_trywait((sem_t *) data); + } + howlongmillis += t.tv_nsec / 1000000; + t.tv_nsec = (howlongmillis % 1000) * 1000000; + t.tv_sec += howlongmillis / 1000; + return sem_timedwait((sem_t *) data, &t); +} + int sl_semaphore::getvalue() { int ret; diff --git a/source/src/tools.h b/source/src/tools.h index fa9f10f5..aed5182d 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -1004,6 +1004,7 @@ struct sl_semaphore ~sl_semaphore(); void wait(); // blocks, until semaphore gets available int trywait(); // returns 0, if semaphore was locked (like wait(), but returns !=0 instead of blocking) + int timedwait(int howlongmillis); // like trywait(), but waits for a litte before returning failure int getvalue(); // returns current semaphore value void post(); // increments (unlocks) semaphore };