Commit graph

3711 commits

Author SHA1 Message Date
f4209f7ea9 Simplify Windows client to react to Ctrl-C always
When select() gets interrupted by SIGINT while a handler is active
without SA_RESTART, it returns immediately with EINTR.  w32_select()
did that only while it waited for standard input to become ready for
reading.  This isn't the case when:

* The client has already received EOF on standard input.  But then the
  action is SIG_DFL, so there was no problem.

* Reading standard input is suspended until the server drains the
  input buffer.  Then reaction to Ctrl-C got delayed until the socket
  got ready, and w32_select() returned normally.  Harmless, because
  the reaction merely appends to the input buffer.

Change w32_select() to match select()'s behavior anyway.
2009-11-30 19:43:50 +01:00
2bfe7a1198 Don't log out player when update aborts a command under Windows
pthread.c's empth_select() returned 1 instead of 0 when empth_wakeup()
interrupted select().  This made io_input() attempt to read input,
which failed with WSAEWOULDBLOCK.  The failure then got propagated all
the way up, and the player got logged out.  Fix by returning 0 in that
case.
2009-11-30 19:43:47 +01:00
ee01ac1912 Fix accepting connections from hosts with "long" IPv6 address
This could fail because struct player member hostaddr had insufficient
space.  Should have been enlarged in commit 19d88af3.
2009-11-30 19:43:47 +01:00
0dbb5bfd75 Plug memory leak on error path in player_accept() 2009-11-30 19:43:47 +01:00
1e1dfc860a Delay shutdown up to 3s to let player output buffers drain 2009-11-30 19:43:47 +01:00
f5885865da Fix player thread race with update_init()
start_server() creates the thread running player_accept() before it
calls update_init().  However, update_init() initializes stuff used to
player threads: update_time[] and play_lock.  In theory, a player
thread could start before that, and crash when taking the
uninitialized play_lock.

Delay starting that tread until after update_init().
2009-11-30 19:43:47 +01:00
0a4d77e919 Simplify checks whether player thread may sleep
A player thread may sleep on input or output, except:

(1) While it is executing a C_MOD command, it may only sleep on input.

(2) While it is being aborted by the update or shutdown, it may not
    sleep at all.

To find out whether a player thread may sleep on input, code has to
check condition (2).  It needs do to that in recvclient().

To find out whether it may sleep on output, it has to check both
conditions.  It needs to do that in pr_player() and upr_player().

The code tracked condition (1) in global variable play_lock_wanted.
It checked condition (2) by examining struct player member command.

Replace all that by new struct player member may_sleep.  Initialize it
in player_new(), update it in dispatch(), shutdwn() and update_run().
This makes the tests in recvclient(), pr_player() and upr_player()
obvious.  play_wrlock_wanted() is now unused, remove it.
2009-11-30 19:43:18 +01:00
bd6d9d53a0 Tweak LWP debug messages 2009-07-19 14:11:53 -04:00
1b4496253d Move queue flush out of io.c
Player threads may only sleep under certain conditions.  In
particular, they must not sleep while a command is being aborted by
the update or shutdown.

io.c should not know about that.  Yet io_output_all() does, because it
needs to give up when update or shutdown interrupt it.  The function
was introduced in Empire 2, but it didn't give up then.  Fixed in
commit a7fa7dee, v4.2.22.  The fix dragged unwanted knowledge of
command abortion into io.c.

To clean up this mess, io_output_all() has to go.

First user is io_write().  io_write() automatically flushes the queue.
In wait-mode, it calls io_output_all() when the queue is longer than
the bufsize, to attempt flushing the queue completely.  In
no-wait-mode, it calls io_output() every bufsize bytes.  Except the
test for that is screwy, so it actually misses some of the flush
conditions.

The automatic flush makes io_write() differ from io_gets(), which is
ugly.  It wasn't present in BSD Empire 1.1.  Remove it again, dropping
io_write()'s last argument.

Flush the queue in its callers pr_player() and upr_player() instead.
Provide new io_output_if_queue_long() for them.  Requires new struct
iop member last_out to keep track of queue growth.  pr_player() and
upr_player() call repeatedly until it makes no more progress.  This
flushes a bit less eagerly in wait-mode, and a bit more eagerly in
non-wait mode.

Second user is recvclient().  It needs to flush the queue before
potentially sleeping in io_input().  Do that with a simple loop around
io_output().  No functional change there.
2009-07-19 14:11:53 -04:00
7fd5b86990 Indentation fix 2009-07-19 14:11:53 -04:00
d052239a7a Make empth_rwlock_t prefer writers
LWP and Windows implementations already did that.  Rewrite the
pthreads implementation.

The write-bias makes the stupid play_wrlock_wanted busy wait in
dispatch() unnecessary.  Remove it.
2009-07-19 14:11:52 -04:00
079fb286c5 Fix lwp_rwlock_unlock() to wake up all readers
It woke up just one.  Bug couldn't bite, because the update never
sleeps, and therefore no reader gets a chance to sleep.
2009-07-19 14:11:52 -04:00
2e4f63c270 Remove IO_NOWAIT, IO_WAIT
They make the code slightly clearer in some places, and more
complicated in others.  Not worth it.
2009-07-19 14:11:52 -04:00
55c53b9add Hide struct io and implementation of struct ioqueue
Move struct io and struct ioqueue from ioqueue.h to ioqueue.c.
Declare incomplete struct ioqueue in ioqueue.h.
2009-07-19 14:11:52 -04:00
6f6c90d406 Make io_output() return a sane value
Return number of bytes written on success, -1 on error.  In
particular, return zero when nothing was written because the queue was
empty, or because the write slept and got woken up, or because the
write refused to sleep.

Before, it instead returned the number of bytes remaining to be
written when empth_select() failed, when woken up from sleep, or
refusing to sleep.  You couldn't tell from the return value whether
the call made progress writing out the queue.

The current callers don't actually notice the change.
2009-07-19 14:11:52 -04:00
328adc6fac Clean up bogus setting of IO_EOF in io_output()
Don't set IO_EOF when writev() returns zero.  I don't think this could
happen, but it's wrong anyway, because a short write should not stop
future reads.
2009-07-19 14:11:52 -04:00
3805548b3e Remove blocking struct iop operation
The blocking I/O option makes no sense in the server, because it
blocks the server process instead of the thread.  In fact, it's been
unused since Empire 2, except for one place, where it was used
incorrectly, and got removed in the previous commit.

Make I/O non-blocking in io_open() unconditionally.  Remove IO_NBLOCK
and io_noblocking().
2009-07-19 14:11:52 -04:00
70bc528d0d Remove bogus io_noblocking() from player_login()
The call switched the connection with the player to blocking I/O for
draining of output before closing the connection.  Looks scary,
because blocking on I/O blocks the complete server process, not just
the player thread.  But we don't do input, and we do output only with
IO_WAIT, which can't block.  So this has no effect.
2009-07-19 14:11:52 -04:00
0025f24f1e Remove long defunct IO_NEWSOCK
Chainsaw used this together with the notify callback to make the iop
data type usable for sockets it listened on, so that io_select() could
multiplex them along with the sockets used for actual I/O.
io_select() became unused in Empire 2, and finally got removed in
commit 875d72a0, v4.2.13.  That made the IO_NEWSOCK and the notify
callback defunct.  The latter got removed in commit 7d5a6b81, v4.3.1.
2009-07-19 14:11:52 -04:00
3ce0cea94c Fix race condition in empth_sleep() for Windows
Calculation of sleep duration tried to protect against integer
underflow, but the protection was racy.  Rewrite the whole thing.
2009-07-19 14:11:52 -04:00
9ee9eb3234 Fix empth_sleep() for argument in the past and pthreads
Calculation of sleep duration suffered integer underflow for unsigned
time_t and arguments in the past.  This made empth_sleep() sleep for
"a few" years instead of not at all.
2009-07-19 14:11:52 -04:00
205206b3df Fix fcntl() emulation for Windows
F_GETFL always failed with WSAEINVAL.  io_noblocking() always failed
without doing anything.  Callers didn't check for failure, and newly
opened sockets remained blocking.  But because because
WSAEventSelect() makes sockets non-blocking automatically, they became
non-blocking soon enough to keep things working.

Remove the broken code to query the non-blocking state, and just
return 0.  Document why this works.

While there, simplify the F_SETFL case by using ioctlsocket() instead
of WSAIoctl().
2009-07-19 14:11:52 -04:00
1d1e789782 Make budget's "Sector building" line look better
Number of sectors were not aligned with the other lines.  While there,
print properly plurized "sector" instead of "sct(s)".
2009-07-19 13:58:47 -04:00
44c36fa7d5 Make sector maintenance cost configurable
Replace the fixed $1 per ETU maintenance for capital/city sectors that
are at least 60% efficient by a configurable maintenance cost, payable
regardless of efficiency.  The only change in the default
configuration is that inefficient capitals now pay maintenance.
Charging sector maintenance regardless of efficiency is consistent
with unit maintenance.

New struct dchrstr member d_maint and sector-chr selector maint.  Make
show_sect_build() show it.  Change produce_sect() to record
maintenance in new slot p_sect[SCT_MAINT] instead of abusing
p_sect[SCT_CAPIT].  Replace the "Capital maintenance" line in budget
by "Sector maintenance".
2009-07-19 13:58:47 -04:00
1f60baf818 New SCT_BUDG_MAX 2009-07-19 13:58:47 -04:00
48ff09664b Overhaul show sect b
Print sector type mnemonic and name, like show sect s and c.  Print
"can't" instead of negative number for sectors players can't designate
(this was not an issue before the previous commit).  Show build cost
per 100%, like show ship, land, plane and nuke.  Size the columns more
sensibly.
2009-07-19 13:58:40 -04:00
be6d7ca913 Fix show sect b not to omit undesignatable sectors
show sect b needs to explain any sector players can build.
show_sect_build() omitted sectors players can't designate.  That's
wrong, because players can certainly own and thus build sectors they
can't designate.  Test for infinite mobility cost instead, like
show_sect_stats().
2009-07-19 13:52:55 -04:00
9ff6314a0e Clean up automatic supply leftovers in ship update
Commit 7da69c92 (v4.3.20) removed use of automatic supply from
prod_ship().  It removed bp_enable_cachepath(), but left behind the
final bp_disable_cachepath(); bp_clear_cachepath().  Clean that up.
2009-05-23 10:08:55 +02:00
e0a2b4ca4c Fix mine production resource limit for peffic != 100%
With etu_per_update large and resource depletion quick, a sector can
produce more work than is required to fully deplete a mine.  In that
case, produce() and prod() limit production to what is actually in the
ground.  Except produce() got it wrong for sector types with
production efficiency other than 100%.

This affects mountains in the stock game, but only with impractically
large etu_per_update.
2009-05-21 18:57:55 +02:00
a61e673a07 Clean up poorly chosen loop control variable names
Calling a counting loop's control variable q or x is tasteless
bordering on actively misleading.
2009-05-21 09:30:05 +02:00
a2557a1dec Bump version to 4.3.23 2009-04-30 21:16:56 +02:00
e250301140 Update change log for 4.3.22 2009-04-25 13:57:45 +02:00
70a9a44bbc Fix autoconfiguration of libraries
configure checked for library functions with LIBS instead of
LIBS_server, which could break detection of getaddrinfo() on systems
where LIB_SOCKET isn't empty.

GNUmakefile put @PTHREAD_LIBS@ only in LDLIBS, which breaks linking of
server and possibly client on systems where it is not empty.

Broken in commit 8b778634.
2009-04-25 13:57:45 +02:00
a977bd08f6 Rename m4/my_termlib.m4 to m4/my_terminfo.m4 2009-04-25 13:57:45 +02:00
5e132e3874 Remove useless memset() before free() 2009-04-25 10:16:27 +02:00
20eb6afd15 Fix misuse of CreateThread() in Windows client
We use the C run-time, so we better use its _beginthread(), too.
CreateThread() can lead to deadlocks, at least with some versions of
the C run-time.  Broken in commit f082ef9f, v4.3.11.
2009-04-25 10:16:27 +02:00
d0cf7a3119 Fix Windows client's stdin read thread's error handling
stdin_read_thread() zeroed bounce_status on failure, effectifely
treating it like EOF.  Fix by setting to -1.

It treated main thread termination like failure, and set bounce_error
to a bogus value.  Can't happen, because the program terminates when
the main thread terminates, and the only user of bounce_error is the
main thread anyway.  Regardless, handle the case by terminating,
because that's more obviously correct.

Broken in commit f082ef9f, v4.3.11.
2009-04-25 10:16:27 +02:00
cf4cb6c907 Fix generation of src/client/aclocal.m4
Revert commit c3d2786f, because the resulting aclocal.m4 includes
stuff from outside the standalone build.  Generate with cat instead.
2009-04-25 10:14:42 +02:00
ad0f967fd6 Fix ersatz_getpass() to use its parameter
It used its only actual argument instead.
2009-04-25 10:02:47 +02:00
eb1041f130 Make Windows client read password without echo again
Commit 8c3b8d10 replaced the getpass() for Windows by a generic
ersatz_getpass().  This lost the "switch off echo" feature, with the
excuse that it doesn't work for me (MinGW & Wine).  Turns out it works
under real Windows.  Restore the feature.
2009-04-23 20:38:15 +02:00
b1e6004148 Make savecore put $PWD in the mail subject
Useful when you monitor multiple games.
2009-04-23 20:32:42 +02:00
a9fd8d349b Add includes to make headers self-contained 2009-04-21 19:30:42 +02:00
a78476fcb9 Make configure print a configuration summary 2009-04-19 15:47:40 +02:00
dfb6620203 Autoconfigure use of terminfo
New configure --with-terminfo.  Before, terminfo was assumed to be
available everywhere but on Windows.
2009-04-19 15:42:19 +02:00
e049ad6a56 Declare getsose() & friends in one place 2009-04-19 15:25:45 +02:00
9fb9653ed7 Rebase strptime.c to fix license incompatibility
The old upstream version carries the original BSD license, which is
incompatible with the GPL.  Fix by rebasing to a version that is
licensed under the 2-clause BSD license.
2009-04-18 22:03:39 +02:00
568a288cce Trim a bogus make dependency in standalone client build
It got added in commit f082ef9f.
2009-04-18 19:08:03 +02:00
ce7fab3868 Really, really fix bomb not to wipe out plane updates
Commit 82b5e3c2 missed escorts.
2009-04-18 14:41:24 +02:00
1ee02194c5 Fix tend land not to wipe out concurrent updates
Fix tend_land() to bail out if the tender changed while tend_land()
slept for the last argument (receiving ship).
2009-04-18 08:41:28 +02:00
1329c0e544 Fix return value of s_commod() when it can't draw enough
s_commod() could incorrectly claim success when the sink ended up with
at least as many supplies than were missing initially.  This caused a
number of problems:

* shp_torp() let a ship with two shells fire a torpedo, resulting in
  -1 shells, which then made item_prewrite() oops.  Affected missions
  and return fire, but not the torpedo command.

* shp_missile_defense() let a ship with one shell use missile defense,
  resulting in -1 shells, and the same item_prewrite() oops.

* Land units were considered in supply even when they had not quite
  enough supplies.  Such land units could defend without penalty,
  attack and react.  Commands load and lload weren't affected, because
  they use lnd_in_supply(), which doesn't use s_commod().

Broken in 98f24d5c, v4.3.20.
2009-04-16 13:06:32 +02:00