示例#1
0
文件: game.c 项目: rhencke/fuzzball
/*
 * Named "fork_and_dump()" mostly for historical reasons...
 */
void
fork_and_dump(void)
{
	epoch++;

#ifndef DISKBASE
	if (global_dumper_pid != 0) {
		wall_wizards("## Dump already in progress.  Skipping redundant scheduled dump.");
		return;
	}
#endif

	last_monolithic_time = time(NULL);
	log_status("CHECKPOINTING: %s.#%d#", dumpfile, epoch);

	if (tp_dbdump_warning)
		wall_and_flush(tp_dumping_mesg);

#ifdef DISKBASE
	dump_database_internal();
#else
# ifndef WIN32
	if ((global_dumper_pid=fork())==0) {
	/* We are the child. */
		forked_dump_process_flag = 1;
#  ifdef NICEVAL
	/* Requested by snout of SPR, reduce the priority of the
	 * dumper child. */
		nice(NICEVAL);
#  endif /* NICEVAL */
		set_dumper_signals();
		dump_database_internal();
		_exit(0);
	}
	if (global_dumper_pid < 0) {
	    global_dumper_pid = 0;
	    wall_wizards("## Could not fork for database dumping.  Possibly out of memory.");
	    wall_wizards("## Please restart the server when next convenient.");
	}
# else /* !WIN32 */
	dump_database_internal();
	/* TODO: This is not thread safe - disabled for now... */
	/*global_dumper_pid = (long) _beginthread(fork_dump_thread, 0, 0);
	if (global_dumper_pid == -1L) {
		wall_wizards("## Could not create thread for database dumping");
	}*/
# endif
#endif
}
示例#2
0
文件: game.c 项目: revarbat/fuzzball
void
dump_database(void)
{
	epoch++;

	log_status("DUMPING: %s.#%d#", dumpfile, epoch);
	dump_database_internal();
	log_status("DUMPING: %s.#%d# (done)", dumpfile, epoch);
}
示例#3
0
文件: game.c 项目: CyberLeo/protomuck
/*
 * Named "fork_and_dump()" mostly for historical reasons...
 */
void fork_and_dump(void)
{
    epoch++;

    last_monolithic_time = time(NULL);
    log_status("DUMP: %s.#%d#\n", dumpfile, epoch);

    dump_database_internal();
    host_save();
}
示例#4
0
void boot_slave( void ) {
    int sv[2];

    int i;

    int maxfds;

    char *s;

#ifdef HAVE_GETDTABLESIZE
    maxfds = getdtablesize();
#else
    maxfds = sysconf( _SC_OPEN_MAX );
#endif

    if( slave_socket != -1 ) {
        close( slave_socket );
        slave_socket = -1;
    }
    if( socketpair( AF_UNIX, SOCK_DGRAM, 0, sv ) < 0 ) {
        return;
    }
    /*
     * set to nonblocking
     */
#ifdef FNDELAY
    if( fcntl( sv[0], F_SETFL, FNDELAY ) == -1 ) {
#else
    if( fcntl( sv[0], F_SETFL, O_NDELAY ) == -1 ) {
#endif
        close( sv[0] );
        close( sv[1] );
        return;
    }
    slave_pid = vfork();
    switch( slave_pid ) {
    case -1:
        close( sv[0] );
        close( sv[1] );
        return;

    case 0:		/* child */
        close( sv[0] );
        if( dup2( sv[1], 0 ) == -1 ) {
            _exit( 1 );
        }
        if( dup2( sv[1], 1 ) == -1 ) {
            _exit( 1 );
        }
        for( i = 3; i < maxfds; ++i ) {
            close( i );
        }
        s = ( char * ) XMALLOC( MBUF_SIZE, "boot_slave" );
        sprintf( s, "%s/slave", mudconf.binhome );
        execlp( s, "slave", NULL );
        XFREE( s, "boot_slave" );
        _exit( 1 );
    }
    close( sv[1] );

#ifdef FNDELAY
    if( fcntl( sv[0], F_SETFL, FNDELAY ) == -1 ) {
#else
    if( fcntl( sv[0], F_SETFL, O_NDELAY ) == -1 ) {
#endif
        close( sv[0] );
        return;
    }
    slave_socket = sv[0];
    log_write( LOG_ALWAYS, "NET", "SLAVE", "DNS lookup slave started on fd %d", slave_socket );
}

int make_socket( int port ) {
    int s, opt;

    struct sockaddr_in server;

    s = socket( AF_INET, SOCK_STREAM, 0 );
    if( s < 0 ) {
        log_perror( "NET", "FAIL", NULL, "creating master socket" );
        exit( 3 );
    }
    opt = 1;
    if( setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
                    ( char * ) &opt, sizeof( opt ) ) < 0 ) {
        log_perror( "NET", "FAIL", NULL, "setsockopt" );
    }
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = ( unsigned short ) htons( ( unsigned short ) port );
    if( !mudstate.restarting )
        if( bind( s, ( struct sockaddr * ) &server, sizeof( server ) ) ) {
            log_perror( "NET", "FAIL", NULL, "bind" );
            close( s );
            exit( 4 );
        }
    listen( s, 5 );
    return s;
}

void shovechars( int port ) {
    fd_set input_set, output_set;

    struct timeval last_slice, current_time, next_slice, timeout,
            slice_timeout;
    int found, check;

    DESC *d, *dnext, *newd;

    int avail_descriptors, maxfds;

    struct stat fstatbuf;

#define CheckInput(x)	FD_ISSET(x, &input_set)
#define CheckOutput(x)	FD_ISSET(x, &output_set)

    mudstate.debug_cmd = ( char * ) "< shovechars >";
    if( !mudstate.restarting ) {
        sock = make_socket( port );
    }
    if( !mudstate.restarting ) {
        maxd = sock + 1;
    }

    get_tod( &last_slice );

#ifdef HAVE_GETDTABLESIZE
    maxfds = getdtablesize();
#else
    maxfds = sysconf( _SC_OPEN_MAX );
#endif

    avail_descriptors = maxfds - 7;

    while( mudstate.shutdown_flag == 0 ) {
        get_tod( &current_time );
        last_slice = update_quotas( last_slice, current_time );

        process_commands();

        if( mudstate.shutdown_flag ) {
            break;
        }

        /*
         * We've gotten a signal to dump flatfiles
         */

        if( mudstate.flatfile_flag && !mudstate.dumping ) {
            if( *mudconf.dump_msg ) {
                raw_broadcast( 0, "%s", mudconf.dump_msg );
            }

            mudstate.dumping = 1;
            log_write( LOG_DBSAVES, "DMP", "CHKPT", "Flatfiling: %s.#%d#", mudconf.db_file, mudstate.epoch );
            dump_database_internal( DUMP_DB_FLATFILE );
            mudstate.dumping = 0;

            if( *mudconf.postdump_msg ) {
                raw_broadcast( 0, "%s", mudconf.postdump_msg );
            }
            mudstate.flatfile_flag = 0;
        }
        /*
         * test for events
         */

        dispatch();

        /*
         * any queued robot commands waiting?
         */

        timeout.tv_sec = que_next();
        timeout.tv_usec = 0;
        next_slice = msec_add( last_slice, mudconf.timeslice );
        slice_timeout = timeval_sub( next_slice, current_time );

        FD_ZERO( &input_set );
        FD_ZERO( &output_set );

        /*
         * Listen for new connections if there are free descriptors
         */

        if( ndescriptors < avail_descriptors ) {
            FD_SET( sock, &input_set );
        }
        /*
         * Listen for replies from the slave socket
         */

        if( slave_socket != -1 ) {
            FD_SET( slave_socket, &input_set );
        }
        /*
         * Mark sockets that we want to test for change in status
         */

        DESC_ITER_ALL( d ) {
            if( !d->input_head ) {
                FD_SET( d->descriptor, &input_set );
            }
            if( d->output_head ) {
                FD_SET( d->descriptor, &output_set );
            }
        }

        /*
         * Wait for something to happen
         */
        found = select( maxd, &input_set, &output_set, ( fd_set * ) NULL,
                        &timeout );

        if( found < 0 ) {
            if( errno == EBADF ) {
                /*
                 * This one is bad, as it results in a spiral
                 * of doom, unless we can figure out what the
                 * bad file descriptor is and get rid of it.
                 */
                log_perror( "NET", "FAIL", "checking for activity", "select" );
                DESC_ITER_ALL( d ) {
                    if( fstat( d->descriptor,
                               &fstatbuf ) < 0 ) {
                        /*
                         * It's a player. Just toss
                         * the connection.
                         */
                        log_write( LOG_PROBLEMS, "ERR", "EBADF", "Bad descriptor %d", d->descriptor );
                        shutdownsock( d,R_SOCKDIED );
                    }
                }
                if( ( slave_socket == -1 ) ||
                        ( fstat( slave_socket, &fstatbuf ) < 0 ) ) {
                    /*
                     * Try to restart the slave, since it
                     * presumably died.
                     */
                    log_write( LOG_PROBLEMS, "ERR", "EBADF", "Bad slave descriptor %d", slave_socket );
                    boot_slave();
                }
                if( ( sock != -1 ) &&
                        ( fstat( sock, &fstatbuf ) < 0 ) ) {
                    /*
                     * That's it, game over.
                     */
                    log_write( LOG_PROBLEMS, "ERR", "EBADF", "Bad game port descriptor %d", sock );
                    break;
                }
            } else if( errno != EINTR ) {
                log_perror( "NET", "FAIL", "checking for activity", "select" );
            }
            continue;
        }