Since we introduced a GLib logging domain, the "client" string appears
twice in the log lines:
client: client 0: command returned 0
Removed the second one, now it looks like this:
client: [0] command returned 0
Still not quite good, but better than before.
GIOChannel is more portable than raw read()/write() calls. We're
using GIOChannel anyway, because we need it for plugging the client
into the GLib main loop.
Configure the GIOChannel to the bare minimum: no character set, no
buffering.
On some platforms, g_free() must be used for memory allocated by
GLib. This patch intends to correct a lot of occurrences, but is
probably not complete.
We are going to migrate away from the concept of notifying the main
thread. There should be events sent to it instead. This patch starts
a series to implement that.
With the GLib main loop, the client manager can install its own event
in case a client is expired. No need for main.c to call
client_manager_expire() manually.
This is a rather huge patch, which unfortunately cannot be splitted.
Instead of using our custom ioops.h library, convert everything to use
the GLib main loop.
When a response is very long (e.g. a large playlist > 100k songs),
most of it will end up in the deferred buffers. Filling the deferred
queue is very expensive currently, because a new buffer is allocated
for every client_write() operation. This may lead to long delays, and
the client might give up and disconnect meanwhile. This patch makes
MPD attempt to flush the deferred queue as often as possible, to work
around this problem. Due to the MPD 0.14 code freeze, we should not
optimize the buffering code now.
Use a literal in the struct declaration, and sizeof(client->buffer)
everywhere else. Also shrink the buffer from 40 kB to 4 kB. The
buffer must only be large enough to hold one line of input, and 4 kB
is still more than enough.
Use memchr() instead of manually traversing the input buffer. Update
the client's properties after all commands have been processed. Check
for buffer overflow once.
"idle" waits until something noteworthy happens on the server,
e.g. song change, playlist modified, database updated. This allows
clients to keep up to date without polling.
The assertion on "!client_is_expired(client)" was wrong, because
writing the command response may cause the client to become expired.
Replace that assertion with a check.
Since the caller chain doesn't care about the return value (except for
COMMAND_RETURN_KILL, COMMAND_RETURN_CLOSE), just return 0 if there is
nothing special. This saves one local variable initialization, and
one access to it.
Also remove one unreachable "return 1" from client_read().
Don't close the client within client_process_line(), return
COMMAND_RETURN_CLOSE instead. This is the signal for the caller chain
to actually close it. This makes dealing with the client pointer a
lot safer, since the caller always knows whether it is still valid.