mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 12:21:19 +00:00
Merge branch 'no-multi-fopen' into 'master'
Prevent multiple nodes fopen-ing the same file See merge request KartKrew/Kart-Public!326
This commit is contained in:
commit
e8dee82341
1 changed files with 78 additions and 24 deletions
102
src/d_netfil.c
102
src/d_netfil.c
|
@ -94,10 +94,20 @@ typedef struct filetran_s
|
||||||
{
|
{
|
||||||
filetx_t *txlist; // Linked list of all files for the node
|
filetx_t *txlist; // Linked list of all files for the node
|
||||||
UINT32 position; // The current position in the file
|
UINT32 position; // The current position in the file
|
||||||
FILE *currentfile; // The file currently being sent/received
|
boolean init; // false if we want to reset position / open a new file
|
||||||
} filetran_t;
|
} filetran_t;
|
||||||
static filetran_t transfer[MAXNETNODES];
|
static filetran_t transfer[MAXNETNODES];
|
||||||
|
|
||||||
|
// The files currently being sent/received
|
||||||
|
typedef struct fileused_s
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
UINT8 count;
|
||||||
|
UINT32 position;
|
||||||
|
} fileused_t;
|
||||||
|
|
||||||
|
static fileused_t transferFiles[UINT8_MAX + 1];
|
||||||
|
|
||||||
// Read time of file: stat _stmtime
|
// Read time of file: stat _stmtime
|
||||||
// Write time of file: utime
|
// Write time of file: utime
|
||||||
|
|
||||||
|
@ -760,8 +770,19 @@ static void SV_EndFileSend(INT32 node)
|
||||||
case SF_FILE: // It's a file, close it and free its filename
|
case SF_FILE: // It's a file, close it and free its filename
|
||||||
if (cv_noticedownload.value)
|
if (cv_noticedownload.value)
|
||||||
CONS_Printf("Ending file transfer (id %d) for node %d\n", p->fileid, node);
|
CONS_Printf("Ending file transfer (id %d) for node %d\n", p->fileid, node);
|
||||||
if (transfer[node].currentfile)
|
if (transferFiles[p->fileid].file)
|
||||||
fclose(transfer[node].currentfile);
|
{
|
||||||
|
if (transferFiles[p->fileid].count > 0)
|
||||||
|
{
|
||||||
|
transferFiles[p->fileid].count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transferFiles[p->fileid].count == 0)
|
||||||
|
{
|
||||||
|
fclose(transferFiles[p->fileid].file);
|
||||||
|
transferFiles[p->fileid].file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
free(p->id.filename);
|
free(p->id.filename);
|
||||||
break;
|
break;
|
||||||
case SF_Z_RAM: // It's a memory block allocated with Z_Alloc or the likes, use Z_Free
|
case SF_Z_RAM: // It's a memory block allocated with Z_Alloc or the likes, use Z_Free
|
||||||
|
@ -778,7 +799,7 @@ static void SV_EndFileSend(INT32 node)
|
||||||
free(p);
|
free(p);
|
||||||
|
|
||||||
// Indicate that the transmission is over
|
// Indicate that the transmission is over
|
||||||
transfer[node].currentfile = NULL;
|
transfer[node].init = false;
|
||||||
|
|
||||||
filestosend--;
|
filestosend--;
|
||||||
}
|
}
|
||||||
|
@ -842,21 +863,31 @@ void SV_FileSendTicker(void)
|
||||||
ram = f->ram;
|
ram = f->ram;
|
||||||
|
|
||||||
// Open the file if it isn't open yet, or
|
// Open the file if it isn't open yet, or
|
||||||
if (!transfer[i].currentfile)
|
if (transfer[i].init == false)
|
||||||
{
|
{
|
||||||
if (!ram) // Sending a file
|
if (!ram) // Sending a file
|
||||||
{
|
{
|
||||||
long filesize;
|
long filesize;
|
||||||
|
|
||||||
transfer[i].currentfile =
|
if (transferFiles[f->fileid].count == 0)
|
||||||
fopen(f->id.filename, "rb");
|
{
|
||||||
|
// It needs opened.
|
||||||
|
transferFiles[f->fileid].file =
|
||||||
|
fopen(f->id.filename, "rb");
|
||||||
|
|
||||||
if (!transfer[i].currentfile)
|
if (!transferFiles[f->fileid].file)
|
||||||
I_Error("File %s does not exist",
|
{
|
||||||
f->id.filename);
|
I_Error("Can't open file %s: %s",
|
||||||
|
f->id.filename, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fseek(transfer[i].currentfile, 0, SEEK_END);
|
// Increment number of nodes using this file.
|
||||||
filesize = ftell(transfer[i].currentfile);
|
I_Assert(transferFiles[f->fileid].count < UINT8_MAX);
|
||||||
|
transferFiles[f->fileid].count++;
|
||||||
|
|
||||||
|
fseek(transferFiles[f->fileid].file, 0, SEEK_END);
|
||||||
|
filesize = ftell(transferFiles[f->fileid].file);
|
||||||
|
|
||||||
// Nobody wants to transfer a file bigger
|
// Nobody wants to transfer a file bigger
|
||||||
// than 4GB!
|
// than 4GB!
|
||||||
|
@ -865,23 +896,43 @@ void SV_FileSendTicker(void)
|
||||||
if (filesize == -1)
|
if (filesize == -1)
|
||||||
I_Error("Error getting filesize of %s", f->id.filename);
|
I_Error("Error getting filesize of %s", f->id.filename);
|
||||||
|
|
||||||
f->size = (UINT32)filesize;
|
f->size = transferFiles[f->fileid].position = (UINT32)filesize;
|
||||||
fseek(transfer[i].currentfile, 0, SEEK_SET);
|
|
||||||
}
|
}
|
||||||
else // Sending RAM
|
|
||||||
transfer[i].currentfile = (FILE *)1; // Set currentfile to a non-null value to indicate that it is open
|
|
||||||
transfer[i].position = 0;
|
transfer[i].position = 0;
|
||||||
|
transfer[i].init = true; // Indicate that it is open
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ram)
|
||||||
|
{
|
||||||
|
// Seek to the right position if we aren't already there.
|
||||||
|
if (transferFiles[f->fileid].position != transfer[i].position)
|
||||||
|
{
|
||||||
|
fseek(transferFiles[f->fileid].file, transfer[i].position, SEEK_SET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a packet containing a file fragment
|
// Build a packet containing a file fragment
|
||||||
p = &netbuffer->u.filetxpak;
|
p = &netbuffer->u.filetxpak;
|
||||||
size = software_MAXPACKETLENGTH - (FILETXHEADER + BASEPACKETSIZE);
|
size = software_MAXPACKETLENGTH - (FILETXHEADER + BASEPACKETSIZE);
|
||||||
if (f->size-transfer[i].position < size)
|
|
||||||
size = f->size-transfer[i].position;
|
if (f->size - transfer[i].position < size)
|
||||||
|
{
|
||||||
|
size = f->size - transfer[i].position;
|
||||||
|
}
|
||||||
|
|
||||||
if (ram)
|
if (ram)
|
||||||
|
{
|
||||||
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
|
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
|
||||||
else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
|
}
|
||||||
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
|
else if (fread(p->data, 1, size, transferFiles[f->fileid].file) != size)
|
||||||
|
{
|
||||||
|
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s",
|
||||||
|
sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transferFiles[f->fileid].file));
|
||||||
|
|
||||||
|
transferFiles[f->fileid].position = (UINT32)(transferFiles[f->fileid].position + size);
|
||||||
|
}
|
||||||
|
|
||||||
p->position = LONG(transfer[i].position);
|
p->position = LONG(transfer[i].position);
|
||||||
// Put flag so receiver knows the total size
|
// Put flag so receiver knows the total size
|
||||||
if (transfer[i].position + size == f->size)
|
if (transfer[i].position + size == f->size)
|
||||||
|
@ -891,15 +942,18 @@ void SV_FileSendTicker(void)
|
||||||
|
|
||||||
// Send the packet
|
// Send the packet
|
||||||
if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
|
if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
|
||||||
{ // Success
|
{
|
||||||
|
// Success
|
||||||
transfer[i].position = (UINT32)(transfer[i].position + size);
|
transfer[i].position = (UINT32)(transfer[i].position + size);
|
||||||
|
|
||||||
if (transfer[i].position == f->size) // Finish?
|
if (transfer[i].position == f->size) // Finish?
|
||||||
|
{
|
||||||
SV_EndFileSend(i);
|
SV_EndFileSend(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Not sent for some odd reason, retry at next call
|
{
|
||||||
if (!ram)
|
// Not sent for some odd reason, retry at next call
|
||||||
fseek(transfer[i].currentfile,transfer[i].position, SEEK_SET);
|
|
||||||
// Exit the while (can't send this one so why should i send the next?)
|
// Exit the while (can't send this one so why should i send the next?)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue