mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-02-06 00:11:05 +00:00
Multithread the exec command
The command itself can be entirely multithreaded, but the reason I did so was just for findfile, which can block for a long time on a slow disk.
This commit is contained in:
parent
c334230bb0
commit
d0e7ba309a
1 changed files with 103 additions and 31 deletions
134
src/command.c
134
src/command.c
|
@ -34,6 +34,17 @@
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "d_netfil.h" // findfile
|
#include "d_netfil.h" // findfile
|
||||||
|
#include "i_threads.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
static I_mutex com_text_mutex;
|
||||||
|
|
||||||
|
# define Lock_state() I_lock_mutex(&com_text_mutex)
|
||||||
|
# define Unlock_state() I_unlock_mutex(com_text_mutex)
|
||||||
|
#else/*HAVE_THREADS*/
|
||||||
|
# define Lock_state()
|
||||||
|
# define Unlock_state()
|
||||||
|
#endif/*HAVE_THREADS*/
|
||||||
|
|
||||||
//========
|
//========
|
||||||
// protos.
|
// protos.
|
||||||
|
@ -119,12 +130,14 @@ void COM_BufAddText(const char *ptext)
|
||||||
|
|
||||||
l = strlen(ptext);
|
l = strlen(ptext);
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
if (com_text.cursize + l >= com_text.maxsize)
|
if (com_text.cursize + l >= com_text.maxsize)
|
||||||
{
|
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n"));
|
||||||
return;
|
else
|
||||||
}
|
VS_Write(&com_text, ptext, l);
|
||||||
VS_Write(&com_text, ptext, l);
|
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds command text and executes it immediately.
|
/** Adds command text and executes it immediately.
|
||||||
|
@ -137,6 +150,8 @@ void COM_BufInsertText(const char *ptext)
|
||||||
char *temp = NULL;
|
char *temp = NULL;
|
||||||
size_t templen;
|
size_t templen;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
// copy off any commands still remaining in the exec buffer
|
// copy off any commands still remaining in the exec buffer
|
||||||
templen = com_text.cursize;
|
templen = com_text.cursize;
|
||||||
if (templen)
|
if (templen)
|
||||||
|
@ -155,6 +170,8 @@ void COM_BufInsertText(const char *ptext)
|
||||||
VS_Write(&com_text, temp, templen);
|
VS_Write(&com_text, temp, templen);
|
||||||
Z_Free(temp);
|
Z_Free(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Progress the wait timer and flush waiting console commands when ready.
|
/** Progress the wait timer and flush waiting console commands when ready.
|
||||||
|
@ -180,6 +197,8 @@ void COM_BufExecute(void)
|
||||||
char line[1024] = "";
|
char line[1024] = "";
|
||||||
INT32 quotes;
|
INT32 quotes;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
while (com_text.cursize)
|
while (com_text.cursize)
|
||||||
{
|
{
|
||||||
// find a '\n' or; line break
|
// find a '\n' or; line break
|
||||||
|
@ -227,6 +246,8 @@ void COM_BufExecute(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Executes a string immediately. Used for skirting around WAIT commands.
|
/** Executes a string immediately. Used for skirting around WAIT commands.
|
||||||
|
@ -672,12 +693,79 @@ static void COM_CEchoDuration_f(void)
|
||||||
HU_SetCEchoDuration(atoi(COM_Argv(1)));
|
HU_SetCEchoDuration(atoi(COM_Argv(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct COM_Exec_Ctx
|
||||||
|
{
|
||||||
|
char * filename;
|
||||||
|
boolean noerror;
|
||||||
|
boolean silent;
|
||||||
|
UINT8 * buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Free_COM_Exec_Ctx (struct COM_Exec_Ctx *ctx)
|
||||||
|
{
|
||||||
|
Z_Free(ctx->buf);
|
||||||
|
free(ctx->filename);
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void COM_Exec_Thread (struct COM_Exec_Ctx *ctx)
|
||||||
|
{
|
||||||
|
char filename[256];
|
||||||
|
|
||||||
|
ctx->buf = NULL;
|
||||||
|
|
||||||
|
// load file
|
||||||
|
// Try with Argv passed verbatim first, for back compat
|
||||||
|
FIL_ReadFile(ctx->filename, &buf);
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
if (I_thread_is_stopped())
|
||||||
|
{
|
||||||
|
return Free_COM_Exec_Ctx(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
// Now try by searching the file path
|
||||||
|
// filename is modified with the full found path
|
||||||
|
strcpy(filename, ctx->filename);
|
||||||
|
if (findfile(filename, NULL, true) != FS_NOTFOUND)
|
||||||
|
FIL_ReadFile(filename, &buf);
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
if (I_thread_is_stopped())
|
||||||
|
{
|
||||||
|
return Free_COM_Exec_Ctx(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
if (! ctx->silent)
|
||||||
|
CONS_Printf(M_GetText("executing %s\n"), ctx->filename);
|
||||||
|
|
||||||
|
// insert text file into the command buffer
|
||||||
|
COM_BufAddText((char *)buf);
|
||||||
|
COM_BufAddText("\n");
|
||||||
|
|
||||||
|
// free buffer
|
||||||
|
Z_Free(buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (! ctx->noerror)
|
||||||
|
CONS_Printf(M_GetText("couldn't execute file %s\n"), ctx->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** Executes a script file.
|
/** Executes a script file.
|
||||||
*/
|
*/
|
||||||
static void COM_Exec_f(void)
|
static void COM_Exec_f(void)
|
||||||
{
|
{
|
||||||
UINT8 *buf = NULL;
|
struct COM_Exec_Ctx *ctx;
|
||||||
char filename[256];
|
|
||||||
|
|
||||||
if (COM_Argc() < 2 || COM_Argc() > 3)
|
if (COM_Argc() < 2 || COM_Argc() > 3)
|
||||||
{
|
{
|
||||||
|
@ -685,35 +773,19 @@ static void COM_Exec_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load file
|
ctx = malloc(sizeof *ctx);
|
||||||
// Try with Argv passed verbatim first, for back compat
|
|
||||||
FIL_ReadFile(COM_Argv(1), &buf);
|
|
||||||
|
|
||||||
if (!buf)
|
ctx->filename = strdup(COM_Argv(1));
|
||||||
{
|
|
||||||
// Now try by searching the file path
|
|
||||||
// filename is modified with the full found path
|
|
||||||
strcpy(filename, COM_Argv(1));
|
|
||||||
if (findfile(filename, NULL, true) != FS_NOTFOUND)
|
|
||||||
FIL_ReadFile(filename, &buf);
|
|
||||||
|
|
||||||
if (!buf)
|
ctx->noerror = COM_CheckParm("-noerror");
|
||||||
{
|
ctx->silent = COM_CheckParm("-silent");
|
||||||
if (!COM_CheckParm("-noerror"))
|
|
||||||
CONS_Printf(M_GetText("couldn't execute file %s\n"), COM_Argv(1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!COM_CheckParm("-silent"))
|
#ifdef HAVE_THREADS
|
||||||
CONS_Printf(M_GetText("executing %s\n"), COM_Argv(1));
|
I_spawn_thread("exec-command", (I_thread_fn)COM_Exec_Thread, ctx);
|
||||||
|
#else
|
||||||
|
COM_Exec_Thread(ctx);
|
||||||
|
#endif
|
||||||
|
|
||||||
// insert text file into the command buffer
|
|
||||||
COM_BufAddText((char *)buf);
|
|
||||||
COM_BufAddText("\n");
|
|
||||||
|
|
||||||
// free buffer
|
|
||||||
Z_Free(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Delays execution of the rest of the commands until the next frame.
|
/** Delays execution of the rest of the commands until the next frame.
|
||||||
|
|
Loading…
Reference in a new issue