Commit Graph

14 Commits

Author SHA1 Message Date
Zhou Qiankang
9c1226223c tests/gio: skip Unix socket-mock tests on Windows
Signed-off-by: Zhou Qiankang <wszqkzqk@qq.com>
2025-08-19 21:31:13 +08:00
Philip Withnall
2326db507d tests: Add a missing poll condition to socket-listener test
It’s possible for the server communications to finish one main context
iteration before all of the client communications, depending on how the
kernel queues socket connection messages.

Fixes CI failure: https://gitlab.gnome.org/GNOME/glib/-/jobs/5341950

```
GLib-GIO:ERROR:../gio/tests/socket-listener.c:639:test_accept_multi_simultaneously: 'clients[i].result' should not be NULL
not ok /socket-listener/accept/multi-simultaneously - GLib-GIO:ERROR:../gio/tests/socket-listener.c:639:test_accept_multi_simultaneously: 'clients[i].result' should not be NULL
```

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-07-31 00:11:25 +01:00
Philip Withnall
8b82fb34c9 gsocketlistener: Fix infinite blocking when accepting connections
As the new comments in the code try to explain, this fixes infinite
blocking which could happen when calling
`g_socket_listener_accept_async()` multiple times in parallel, with more
parallel calls than there are pending incoming connections on any of the
`GSocket`s in the `GSocketListener`.

The way `g_socket_listener_accept_async()` works is to create a set of
`GSocketSource`s when it’s called, one for each of the `GSocket`s in the
`GSocketListener`. Those sources are attached to the main context,
polling for `G_IO_IN` (indicating that the socket has a pending incoming
connection to accept).

When one of the socket sources polls ready, `g_socket_accept()` is
called on it, and a new connection is created.

If there are multiple pending `g_socket_listener_accept_async()` calls,
there are correspondingly multiple `GSocketSource` sources for each
`GSocket` in the `GSocketListener`. They will all poll ready in a single
`GMainContext` iteration. The first one to be dispatched will
successfully call `g_socket_accept()`, and subsequent ones to dispatch
will do likewise until there are no more pending incoming connections.
At that point, any remaining socket sources polling ready in that
`GMainContext` iteration will call `g_socket_accept()` on a socket which
is *not* ready to accept, and that will block indefinitely, because
`GSocket` has its own blocking layer on top of `poll()`.

This is not great.

It seems like a better approach would be to disable `GSocket`’s blocking
code, because `GSocketListener` is using `poll()` directly. We only need
one source of poll truth. So, do that.

Unfortunately, that’s complicated by the fact that
`g_socket_listener_add_socket()` allows third party code to provide its
own `GSocket`s to listen on. We probably can’t unilaterally change those
to non-blocking mode, so users of that API will get what they ask for.
That might include blocking indefinitely. I’ve adjusted the
documentation to mention that, at least.

The changes are fairly simple; the accompanying unit test is less
simple. Shrug. It tests for the scenario fixed by this commit, plus the
scenario fixed by the previous commit.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3739
2025-07-25 16:36:33 +01:00
Philip Withnall
9fe6d8b5f0 tests: Disable socket-listener mock tests on macOS
Its symbol interposition works differently to that of Linux, so our
approach using `dlsym(RTLD_NEXT)` to inject syscalls (and still allow
chaining up to the version from libc) doesn’t work on macOS.

See https://gitlab.gnome.org/GNOME/glib/-/jobs/4861349 for an example
failure.

It would be lovely to have these tests working on macOS, but I am not a
macOS developer, and have spent enough time fixing this leak (#1250)
already. It can wait for follow-up work.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #1250
2025-03-13 13:25:19 +00:00
Philip Withnall
05e529f3f8 tests: Add tests for g_socket_listener_add_any_inet_port() algorithm
The algorithm that `g_socket_listener_add_any_inet_port()` and
`g_socket_listener_add_inet_port()` use to try to connect to IPv4 and/or
IPv6 ports are a bit complex (especially when port allocation has to
happen in the former method). So far they’ve not really been unit
tested, which is unfortunate, and has left latent bugs.

Add some unit tests for both methods, by providing mock `socket()` (and
friends) functions to override those from libc, and using those to cause
specific syscalls to fail according to the test’s needs.

These tests demonstrate the fix for #1250 works, as the tests can be run
under memcheck and show no memory leaks. They’ve revealed a follow-up
issue, though — `g_socket_listener_add_any_inet_port()` doesn’t try a
fallback IPv4-only socket if it tries an IPv6 socket and that socket
accepts IPv4 but then fails to `listen()`. I’ve filed issue #3604 for
that.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #1250
2025-03-13 13:25:06 +00:00
Philip Withnall
c613d32b92 tests: Add SPDX license headers automatically
Add SPDX license (but not copyright) headers to all files which follow a
certain pattern in their existing non-machine-readable header comment.

This commit was entirely generated using the command:
```
git ls-files gio/tests/*.c | xargs perl -0777 -pi -e 's/\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/\n \*\n \* SPDX-License-Identifier: LGPL-2.1-or-later\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/igs'
```

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #1415
2022-05-18 09:20:07 +01:00
Philip Withnall
7e9585177d tests: Drop use of g_test_bug_base()
Include the base URI in the `g_test_bug()` calls instead. This resolves
inconsistencies between the old bug base (bugzilla.gnome.org) and the
new bug base (gitlab.gnome.org). It also has the advantage that the URI
passed to `g_test_bug()` is now clickable in the code editor, rather
than being split across two locations.

See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/275#note_303175

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2021-05-13 22:16:27 +01:00
Simon McVittie
44c004c84e Normalize C source files to end with exactly one newline
Some editors automatically remove trailing blank lines, or
automatically add a trailing newline to avoid having a trailing
non-blank line that is not terminated by a newline. To avoid unrelated
whitespace changes when users of such editors contribute to GLib,
let's pre-emptively normalize all files.

Unlike more intrusive whitespace normalization like removing trailing
whitespace from each line, this seems unlikely to cause significant
issues with cherry-picking changes to stable branches.

Implemented by:

    find . -name '*.[ch]' -print0 | \
    xargs -0 perl -0777 -p -i -e 's/\n+\z//g; s/\z/\n/g'

Signed-off-by: Simon McVittie <smcv@collabora.com>
2020-06-10 09:48:02 +01:00
Sébastien Wilmet
d9a44b66af gio/tests/: LGPLv2+ -> LGPLv2.1+
A lot of tests in gio/tests/ don't have a license header.

https://bugzilla.gnome.org/show_bug.cgi?id=776504
2017-05-29 19:53:34 +02:00
Dan Winship
6de5595570 Fix gio/tests/socket-listener
g_socket_listener_add_address() is synchronous; all of the events will
have been emitted before it returns and it doesn't queue any sources.
The test was unintentionally depending on the fact that
g_main_context_iterate(NULL, TRUE) would return anyway (at least the
first time it was called), but that's no longer true after e4ee307.

https://bugzilla.gnome.org/show_bug.cgi?id=768968
2016-07-19 17:22:07 -04:00
Paolo Borelli
45e99833e3 Move a unit test to the right file
Move a test for threaded socket service to socket-service.c.
2015-07-20 00:00:42 +02:00
Paolo Borelli
b64e2956f6 Add an event signal to GSocketListener
This allows the caller to know when a socket has been bound so that
it can for instance set the SO_SENDBUF and SO_RECVBUF socket options
before listen is called

https://bugzilla.gnome.org/show_bug.cgi?id=738207
2015-04-04 21:26:15 +02:00
Ross Lagerwall
7d9816934e gio/tests: Prevent hangs and aborts in socket-listener
Fix two problems:
1) If g_socket_service_stop is called before the accept call is requeued,
then the reference count won't decrease and this code will hang forever:
  while (G_OBJECT (service)->ref_count == ref_count)
    g_main_context_iteration (NULL, TRUE);

2) Sometimes the testcase fails (maybe 1 in 200 times for me):
GLib-GIO:ERROR:socket-listener.c:73:connection_cb: assertion failed
(G_OBJECT (service)->ref_count == 2): (3 == 2)
Aborted (core dumped)

The problem is that depending on ordering, cancellation of the async
listener can require further main context iterations before it releases
the reference on the socket service. Furthermore, in some cases, it
requires at least one iteration.

https://bugzilla.gnome.org/show_bug.cgi?id=712570
2014-12-07 08:40:18 +02:00
Dan Winship
e784a4ba32 gio/tests: add a socket-listener test
Add a GSocketListener test program. Currently the only test is a
regression test for bug 712570 (based on a standalone bug reproducer
provided by Ross Lagerwall).
2014-11-23 12:33:01 -05:00