Fix potential problem. Some cleanup.

This commit is contained in:
Themaister 2011-02-18 23:51:51 +01:00
parent 9be3c13a07
commit e482b1bd18
5 changed files with 80 additions and 41 deletions

View File

@ -122,3 +122,23 @@ void autosave_free(autosave_t *handle)
free(handle->buffer);
free(handle);
}
void lock_autosave(void)
{
for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++)
{
if (g_extern.autosave[i])
autosave_lock(g_extern.autosave[i]);
}
}
void unlock_autosave(void)
{
for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++)
{
if (g_extern.autosave[i])
autosave_unlock(g_extern.autosave[i]);
}
}

View File

@ -27,5 +27,7 @@ void autosave_lock(autosave_t *handle);
void autosave_unlock(autosave_t *handle);
void autosave_free(autosave_t *handle);
void lock_autosave(void);
void unlock_autosave(void);
#endif

View File

@ -43,6 +43,8 @@
#define MAX_PLAYERS 5
#define MAX_BINDS 25 // Needs to be increased every time there are new binds added.
#define SSNES_NO_JOYPAD 0xFFFF
// All config related settings go here.
struct settings
{
struct
@ -108,6 +110,7 @@ enum ssnes_game_type
SSNES_CART_SUFAMI,
};
// All run-time- / command line flag-related globals go here.
struct global
{
bool verbose;
@ -166,19 +169,24 @@ struct global
msg_queue_t *msg_queue;
// Rewind support.
state_manager_t *state_manager;
void *state_buf;
bool frame_is_reverse;
// Movie record support
bsv_movie_t *bsv_movie;
char bsv_movie_path[256];
bool bsv_movie_end;
bool bsv_movie_playback;
// Pausing support
bool is_paused;
// Autosave support.
autosave_t *autosave[2];
// Netplay.
netplay_t *netplay;
char netplay_server[256];
bool netplay_enable;
@ -186,6 +194,7 @@ struct global
unsigned netplay_sync_frames;
uint16_t netplay_port;
// FFmpeg record.
#ifdef HAVE_FFMPEG
ffemu_t *rec;
char record_path[256];

View File

@ -18,6 +18,7 @@
#include "netplay.h"
#include "general.h"
#include "dynamic.h"
#include "autosave.h"
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
@ -387,6 +388,27 @@ bool netplay_is_alive(netplay_t *handle)
return handle->has_connection;
}
static bool send_chunk(netplay_t *handle)
{
const struct sockaddr *addr = NULL;
if (handle->addr)
addr = handle->addr->ai_addr;
else if (handle->has_client_addr)
addr = (const struct sockaddr*)&handle->their_addr;
if (addr)
{
if (sendto(handle->udp_fd, CONST_CAST handle->packet_buffer, sizeof(handle->packet_buffer), 0, addr, sizeof(struct sockaddr)) != sizeof(handle->packet_buffer))
{
SSNES_WARN("Netplay connection hung up. Will continue without netplay.\n");
handle->has_connection = false;
return false;
}
}
return true;
}
#define MAX_RETRIES 16
static int poll_input(netplay_t *handle, bool block)
{
@ -395,19 +417,30 @@ static int poll_input(netplay_t *handle, bool block)
FD_SET(handle->udp_fd, &fds);
struct timeval tv = {
.tv_sec = block ? 5 : 0,
.tv_usec = 0
.tv_sec = 0,
.tv_usec = block ? 500000 : 0
};
if (select(handle->udp_fd + 1, &fds, NULL, NULL, &tv) < 0)
int i = 0;
do
{
if (select(handle->udp_fd + 1, &fds, NULL, NULL, &tv) < 0)
return -1;
if (FD_ISSET(handle->udp_fd, &fds))
return 1;
if (block && !send_chunk(handle))
{
SSNES_WARN("Netplay connection hung up. Will continue without netplay.\n");
handle->has_connection = false;
return false;
}
} while (i++ < MAX_RETRIES && block);
if (block)
return -1;
if (block && !FD_ISSET(handle->udp_fd, &fds))
return -1;
if (FD_ISSET(handle->udp_fd, &fds))
return 1;
return 0;
}
@ -431,20 +464,11 @@ static bool get_self_input_state(netplay_t *handle)
handle->packet_buffer[(UDP_FRAME_PACKETS - 1) * 2] = htonl(handle->frame_count);
handle->packet_buffer[(UDP_FRAME_PACKETS - 1) * 2 + 1] = htonl(state);
const struct sockaddr *addr = NULL;
if (handle->addr)
addr = handle->addr->ai_addr;
else if (handle->has_client_addr)
addr = (const struct sockaddr*)&handle->their_addr;
if (addr)
if (!send_chunk(handle))
{
if (sendto(handle->udp_fd, CONST_CAST handle->packet_buffer, sizeof(handle->packet_buffer), 0, addr, sizeof(struct sockaddr)) != sizeof(handle->packet_buffer))
{
SSNES_WARN("Netplay connection hung up. Will continue without netplay.\n");
handle->has_connection = false;
return false;
}
SSNES_WARN("Netplay connection hung up. Will continue without netplay.\n");
handle->has_connection = false;
return false;
}
ptr->self_state = state;
@ -647,7 +671,9 @@ void netplay_post_frame(netplay_t *handle)
while (handle->tmp_ptr != handle->self_ptr)
{
psnes_serialize(handle->buffer[handle->tmp_ptr].state, handle->state_size);
lock_autosave();
psnes_run();
unlock_autosave();
handle->tmp_ptr = NEXT_PTR(handle->tmp_ptr);
}
handle->other_ptr = handle->read_ptr;

18
ssnes.c
View File

@ -871,24 +871,6 @@ static void deinit_autosave(void)
}
}
static void lock_autosave(void)
{
for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++)
{
if (g_extern.autosave[i])
autosave_lock(g_extern.autosave[i]);
}
}
static void unlock_autosave(void)
{
for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++)
{
if (g_extern.autosave[i])
autosave_unlock(g_extern.autosave[i]);
}
}
static void fill_pathnames(void)
{
switch (g_extern.game_type)