1
0
Fork 0
flightgear/Tools/Construct/Parallel/server.cxx

262 lines
5.6 KiB
C++
Raw Normal View History

1999-05-15 01:08:00 +00:00
// remote_server.c -- Written by Curtis Olson
// -- for CSci 5502
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h> // for stat()
#include <unistd.h>
1999-05-15 01:08:00 +00:00
#include <sys/socket.h> // bind
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/wait.h>
1999-05-15 01:08:00 +00:00
#include <iostream>
#include <string>
1999-05-15 01:08:00 +00:00
#include <Bucket/newbucket.hxx>
1999-05-15 01:08:00 +00:00
#define MAXBUF 1024
static double lat = 0.0;
static double lon = 0.0;
static double dy = 0.0;
static int pass = 0;
1999-05-15 01:08:00 +00:00
int make_socket (unsigned short int* port) {
int sock;
struct sockaddr_in name;
socklen_t length;
// Create the socket.
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror ("socket");
exit (EXIT_FAILURE);
}
// Give the socket a name.
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = 0 /* htons (port) */;
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
perror ("bind");
exit (EXIT_FAILURE);
}
// Find the assigned port number
length = sizeof(struct sockaddr_in);
if ( getsockname(sock, (struct sockaddr *) &name, &length) ) {
perror("Cannot get socket's port number");
}
*port = ntohs(name.sin_port);
return sock;
}
#if 0 // better move this to client
// return true if file exists
static bool file_exists( const string& file ) {
struct stat buf;
if ( stat( file.c_str(), &buf ) == 0 ) {
return true;
} else {
return false;
}
}
// check if the specified tile has data defined for it
static bool has_data( const string& path, const FGBucket& b ) {
string dem_file = path + ".dem" + "/Scenery/" + b.gen_base_path()
+ "/" + b.gen_index_str() + ".dem";
if ( file_exists( dem_file ) ) {
return true;
}
dem_file += ".gz";
if ( file_exists( dem_file ) ) {
return true;
}
return false;
}
#endif
// initialize the tile counting system
void init_tile_count() {
// pre-pass
pass = 0;
// initial bogus value
lat = 100;
// determine tile height
FGBucket tmp1( 0.0, 0.0 );
dy = tmp1.get_height();
}
// return the next tile
long int get_next_tile( const string& work_base, const string& output_base )
{
FGBucket b;
static double shift_over = 0.0;
static double shift_up = 0.0;
// cout << "lon = " << lon << " lat = " << lat << endl;
if ( lat > 90.0 ) {
++pass;
if ( pass == 1 ) {
shift_over = 0.0;
shift_up = 0.0;
} else if ( pass == 2 ) {
shift_over = 1.0;
shift_up = 0.0;
} else if ( pass == 3 ) {
shift_over = 0.0;
shift_up = 1.0;
} else if ( pass == 4 ) {
shift_over = 1.0;
shift_up = 1.0;
} else {
return -1;
}
// reset lat
lat = -89.0 + (shift_up*dy) - (dy*0.5);
// reset lon
FGBucket tmp( 0.0, lat );
double dx = tmp.get_width();
lon = -180 + (shift_over*dx) + (dx*0.5);
cout << "starting pass = " << pass
<< " with lat = " << lat << " lon = " << lon << endl;
}
// if ( ! start_lon ) {
// lon = -180 + dx * 0.5;
// } else {
// start_lon = false;
// }
if ( lon > 180.0 ) {
// increment to next row
// skip every other row (to avoid two clients working on
// adjacent tiles)
lat += 2.0 * dy;
FGBucket tmp( 0.0, lat );
double dx = tmp.get_width();
lon = -180 + (shift_over*dx) + (dx*0.5);
}
b = FGBucket( lon, lat );
1999-05-17 17:43:52 +00:00
cout << "Bucket = " << b << " (" << pass << ")" << endl;
// increment to next tile
FGBucket tmp( 0.0, lat );
double dx = tmp.get_width();
// skip every other column (to avoid two clients working on
// adjacent tiles)
lon += 2.0 * dx;
return b.gen_index();
}
// display usage and exit
void usage( const string name ) {
cout << "Usage: " << name << " <work_base> <output_base>" << endl;
exit(-1);
}
int main( int argc, char **argv ) {
long int next_tile;
1999-05-15 01:08:00 +00:00
int sock, msgsock, length, pid;
fd_set ready;
short unsigned int port;
// quick argument sanity check
if ( argc < 3 ) {
usage( argv[0] );
}
1999-05-15 01:08:00 +00:00
string work_base = argv[1];
string output_base = argv[2];
// initialize tile counter / incrementer
init_tile_count();
// setup socket to listen on
sock = make_socket( &port );
1999-05-15 01:08:00 +00:00
cout << "socket is connected to port = " << port << endl;
// Specify the maximum length of the connection queue
1999-05-17 17:43:52 +00:00
listen(sock, 10);
1999-05-15 01:08:00 +00:00
for ( ;; ) {
FD_ZERO(&ready);
FD_SET(sock, &ready);
// block until we get some input on sock
1999-05-15 01:08:00 +00:00
select(32, &ready, 0, 0, NULL);
if ( FD_ISSET(sock, &ready) ) {
// printf("%d %d Incomming message --> ", getpid(), pid);
// get the next tile to work on
next_tile = get_next_tile(work_base, output_base);
1999-05-17 17:43:52 +00:00
// cout << "next tile = " << next_tile << endl;;
1999-05-15 01:08:00 +00:00
msgsock = accept(sock, 0, 0);
// cout << "msgsock = " << msgsock << endl;
1999-05-15 01:08:00 +00:00
// spawn a child
1999-05-15 01:08:00 +00:00
pid = fork();
if ( pid < 0 ) {
// error
1999-05-15 01:08:00 +00:00
perror("Cannot fork child process");
exit(-1);
} else if ( pid > 0 ) {
// This is the parent
1999-05-15 01:08:00 +00:00
close(msgsock);
// clean up all of our zombie children
int status;
while ( (pid = waitpid( WAIT_ANY, &status, WNOHANG )) > 0 ) {
// cout << "waitpid() returned " << pid << endl;
}
} else {
// This is the child
1999-05-15 01:08:00 +00:00
// cout << "new process started to handle new connection for "
// << next_tile << endl;
1999-05-15 01:08:00 +00:00
// reply to the client
char message[MAXBUF];
sprintf(message, "%ld", next_tile);
length = strlen(message);
if ( write(msgsock, message, length) < 0 ) {
perror("Cannot write to stream socket");
1999-05-15 01:08:00 +00:00
}
close(msgsock);
// cout << "process for " << next_tile << " ended" << endl;
1999-05-15 01:08:00 +00:00
exit(0);
}
}
}
}