mirror of
https://salsa.debian.org/ha-team/libqb
synced 2026-08-12 13:04:57 +00:00
Imported Upstream version 0.14.2
This commit is contained in:
parent
85f75e9d49
commit
8da8cdf17a
@ -1 +1 @@
|
||||
0.11.1
|
||||
0.14.2
|
||||
|
||||
623
ChangeLog
623
ChangeLog
@ -1,3 +1,626 @@
|
||||
2012-09-10 The Quarterback Library Release Team <quarterback-devel@fedorahosted.org>
|
||||
|
||||
Fix "make distcheck"
|
||||
|
||||
Bump the version to 0.14.2
|
||||
|
||||
2012-09-07 Виноградов Василий <wmdlr@yandex.ru>
|
||||
|
||||
Get libqb building on cygwin.
|
||||
|
||||
2012-09-06 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Merge pull request #42 from jsgf/master
|
||||
Three fixes for ipc_us.c
|
||||
|
||||
2012-09-06 Jeremy Fitzhardinge <jeremy@exablox.com>
|
||||
|
||||
ipc_us: slightly more robust cmsg handling
|
||||
Cope with multiple cmsg structures in the received msg.
|
||||
|
||||
ipc_us: on Linux, set SO_PASSCRED on the sending socket too
|
||||
Linux doesn't pass credential information by default, only when it has
|
||||
been specifically requested with SO_PASSCRED. This means there's a
|
||||
race between when the ipc server side has set up and is listening on the
|
||||
socket, and when the client may connect; if the client connects and sends
|
||||
its first message before the server has set SO_PASSCRED on the socket,
|
||||
then there will be no ucred information associated with the message.
|
||||
|
||||
The fix is to set SO_PASSCRED on the client socket as well, so that
|
||||
the message will always have a ucred associated with it when the server
|
||||
reads it.
|
||||
|
||||
Without this change, around 1% of cpg_model_initialize() calls fail
|
||||
with CS_ERR_ACCESS.
|
||||
|
||||
(This Linux behaviour was introduced just on a year ago in
|
||||
16e5726269611b71c930054ffe9b858c1cea88eb "af_unix: dont send
|
||||
SCM_CREDENTIALS by default".)
|
||||
|
||||
ipc_us: clear request unused fields
|
||||
Clear unused request fields and padding so that valgrind doesn't complain
|
||||
about undefined data being sent over the socket.
|
||||
|
||||
2012-09-05 Andrew Beekhof <andrew@beekhof.net>
|
||||
|
||||
TEST: Include writing and reading the blackbox in the log_long_msg test
|
||||
|
||||
2012-09-05 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
LOG: fix qb_vsnprintf_deserialize()
|
||||
the strlcat was not call correctly, it needs the
|
||||
original string to find the end and return the
|
||||
correct length.
|
||||
|
||||
2012-09-01 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Merge pull request #41 from jsgf/master
|
||||
Fix some 64-bit big-endian issues
|
||||
|
||||
2012-09-01 Jeremy Fitzhardinge <jeremy@goop.org>
|
||||
|
||||
blackbox: fix 64-bit big-endian issues
|
||||
Two issues:
|
||||
1. when writing out the function name length, don't just write the 4 MSB
|
||||
of the size
|
||||
2. when reading the time, don't just use the 4 MSB of the time as the
|
||||
timestamp; the log contains a full time_t, so we may as well use it.
|
||||
|
||||
2012-08-31 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Remove IPC_NEEDS_RESPONSE_ACK and turn off shm ipc on solaris
|
||||
|
||||
Define unix path max for openbsd
|
||||
|
||||
Only turn on ipc_needs_response_ack=yes for solaris
|
||||
Hopefully I can kill this option.
|
||||
|
||||
Some improvements to kqueue usage.
|
||||
|
||||
2012-08-30 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
kqueue: drop log message to trace.
|
||||
|
||||
2012-08-29 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Fix splint warning
|
||||
|
||||
openbsd requires netinet/in.h before arpa/inet.h
|
||||
|
||||
Avoid strcpy() use strlcpy() instead.
|
||||
|
||||
Fix kqueue complile warnings
|
||||
|
||||
openbsd doesn't have EBADMSG
|
||||
|
||||
openbsd has a different UNIX_PATH_MAX
|
||||
103 other bsd's are 108
|
||||
|
||||
LOG: change qb_vsprintf_serialize() into qb_vsnprintf_serialize()
|
||||
This is to prevent overwriting the ringbuffer.
|
||||
Also remove stpcpy() as it is not used anymore.
|
||||
|
||||
TEST: increase timeout to 6 secs as the recv timeout is 5 secs
|
||||
|
||||
TEST: get the logic right - grrr.
|
||||
|
||||
Turn off attribute_section on netbsd
|
||||
|
||||
Some missing pshared semaphore checks
|
||||
|
||||
Cleanup the checks for pshared semaphores
|
||||
|
||||
Add a config check for pthread_mutexattr_setpshared
|
||||
Not available on netbsd
|
||||
|
||||
2012-08-28 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Remove uses of timersub and use qb_util_stopwatch
|
||||
|
||||
RB: change the #error to ENOTSUP if no usable shared process sem
|
||||
This is mainly on mac.
|
||||
|
||||
LOOP-KQUEUE: fix reference before assignment.
|
||||
|
||||
2012-08-27 Fabio M. Di Nitto <fdinitto@redhat.com>
|
||||
|
||||
build: fix libqb.pc creation and make maintainer-clean
|
||||
LIB_RT is unnecessary around. AC_CHECK_LIBS will do the right thing
|
||||
|
||||
similar for the other libs that are all exported via LIBS
|
||||
|
||||
2012-08-27 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
LOG: Make sure the semaphores are initialized.
|
||||
|
||||
2012-08-24 Fabio M. Di Nitto <fdinitto@redhat.com>
|
||||
|
||||
build: remove bashism in cc support check
|
||||
this is required for all systems that don't use bash for /bin/sh
|
||||
|
||||
2012-08-24 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Catch disconnected sockets on Solaris
|
||||
It seems like poll() was not producing a POLLHUP
|
||||
so we rely on qb_ipc_us_recv() returning -ENOTCONN.
|
||||
|
||||
Merge pull request #40 from jsgf/master
|
||||
Merge Jeremy's clang bugfixes.
|
||||
|
||||
2012-08-24 Jeremy Fitzhardinge <jeremy@exablox.com>
|
||||
|
||||
Don't free rb->shared_hdr in qb_rb_create_from_file()
|
||||
Since qb_rb_close() frees it by munmapping it.
|
||||
|
||||
Check error return of qb_ipcs_uc_recv_and_auth()
|
||||
If it fails, then &ugp isn't initialized.
|
||||
|
||||
2012-08-23 Andrew Beekhof <andrew@beekhof.net>
|
||||
|
||||
Fix removal of automatically installed doc files when building rpms
|
||||
|
||||
2012-08-22 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Add the mailing list to the travis email notifications.
|
||||
|
||||
Work around debian not setting the arch path in splint.
|
||||
So just adding both i386 and x86_64 to the path.
|
||||
Ref: http://lists.gnu.org/archive/html/gpsd-dev/2012-05/msg00221.html
|
||||
|
||||
Remove color-tests and parallel-tests automake options.
|
||||
This is just too painful for buildsystems like koji and travis.
|
||||
You can't get access to the detailed output (error logs) that
|
||||
otherwise be printed to screen.
|
||||
I can't find a way to disable them on the command line (that
|
||||
would be the best solution).
|
||||
|
||||
Add travis continuous integration config
|
||||
|
||||
2012-07-20 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Merge pull request #39 from davidvossel/log_tag_fix
|
||||
LOG: Invoke custom log filter function if tag changes
|
||||
|
||||
2012-07-20 David Vossel <dvossel@redhat.com>
|
||||
|
||||
LOG: Invoke custom log filter function if tag changes
|
||||
|
||||
2012-07-19 Jim Meyering <jim@meyering.net>
|
||||
|
||||
tests/rbwriter: don't ignore write failure
|
||||
Here's another fix.
|
||||
In adjusting the printf, I added a cast and switched to %5ld.
|
||||
I would have preferred to use %5jd as the printf format (i.e., then no
|
||||
cast is needed), but saw no other uses of the "j" directive, so perhaps
|
||||
you do not yet depend on printf with such support.
|
||||
|
||||
From 6d5d3af35d1f6851537f7af8996d1106c1ebe435 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Meyering <meyering@redhat.com>
|
||||
Date: Wed, 18 Jul 2012 17:54:38 +0200
|
||||
Subject: [PATCH] tests/rbwriter: don't ignore write failure
|
||||
|
||||
Spotted by coverity:
|
||||
This less-than-zero comparison of an unsigned value is never true.
|
||||
"res < 0U".
|
||||
http://libqb.org/html/0.14.1/coverity/1/7rbwriter.c.html#error
|
||||
|
||||
ipcs: avoid use-after-free for size-0 || disconnect-request
|
||||
Hi,
|
||||
|
||||
Glancing through coverity-reported issues,
|
||||
I saw that this one required attention:
|
||||
|
||||
From 70f1f689022321710405f16dc45b3df30c22bc59 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Meyering <meyering@redhat.com>
|
||||
Date: Wed, 18 Jul 2012 17:34:17 +0200
|
||||
Subject: [PATCH] ipcs: avoid use-after-free for size-0 || disconnect-request
|
||||
|
||||
spotted by coverity:
|
||||
http://libqb.org/html/0.14.1/coverity/1/265ipcs.c.html#error
|
||||
|
||||
2012-07-17 The Quarterback Library Release Team <quarterback-devel@fedorahosted.org>
|
||||
|
||||
Bump the version to 0.14.1
|
||||
|
||||
2012-07-17 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
RB: set the new read pointer after clearing the header.
|
||||
This is to prevent a situation where a fast writer will
|
||||
write their new chunk between setting the new read pointer
|
||||
and clearing the header.
|
||||
|
||||
RB: improve the debug print outs
|
||||
|
||||
RB: be more explicit about the word alignment
|
||||
|
||||
RB: cleanup the macros for wrapping the index
|
||||
|
||||
RB: use sem_getvalue as a tie breaker when read_pt == write_pt
|
||||
|
||||
RB: if read or peek don't get the message then re-post to the semaphore
|
||||
|
||||
RB: convert the rb_peek() status into a recv like status.
|
||||
peek returns 0 on no data, so convert that to -EAGAIN.
|
||||
|
||||
RB: use internal reclaim function
|
||||
|
||||
IPC: use calloc instead of malloc to fix valgrind warnings
|
||||
This is to cleanup some valgrind warnings.
|
||||
|
||||
2012-07-14 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Upgrade the doxygen config.
|
||||
The new doxygen says SHOW_DIRECTORIES is deprecated.
|
||||
|
||||
Fix a valgrind error.
|
||||
just use the receive buffer, as it will be big enough.
|
||||
|
||||
2012-06-22 The Quarterback Library Release Team <quarterback-devel@fedorahosted.org>
|
||||
|
||||
Bump the version to 0.14.0
|
||||
|
||||
2012-06-14 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
LOG: fix threaded logging.
|
||||
This has been broken for a year - yikes!
|
||||
Thanks to Voznesensky Vladimir for spotting it.
|
||||
|
||||
2012-06-13 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Add user control of the permissions that are set on the shared mem files
|
||||
|
||||
2012-06-07 Andrew Beekhof <andrew@beekhof.net>
|
||||
|
||||
LOG: Restrict string trucation during serialization to when a precision is specified
|
||||
|
||||
LOG: Gracefully fail when the caller exceeds QB_LOG_MAX_LEN
|
||||
|
||||
LOG: Observe field widths when serializing string arguments
|
||||
|
||||
2012-06-07 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
RB: use the same mechanism in reclaim as read/peek to detect end-of-ring
|
||||
|
||||
2012-06-06 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Add needs_response_ack option to ./check
|
||||
|
||||
RB: fix wrong sem_flg IPC_NOWAIT option
|
||||
The #ifdef was the wrong way around causing
|
||||
the sem to return early with EAGAIN.
|
||||
|
||||
TESTS: fix warning about unused functions
|
||||
|
||||
Remove D_FORTIFY_SOURCE from check.
|
||||
Can't seem to get this to work on F17.
|
||||
|
||||
Open shared mem file in /dev/shm only for linux
|
||||
|
||||
Don't use msg_flags on solaris (recvmsg).
|
||||
|
||||
Turn off attribute_section on solaris
|
||||
|
||||
ipc example: add -e (events) option
|
||||
use events instead of responses
|
||||
|
||||
IPC: if the server returns EAGAIN or ETIMEOUT the check the connection
|
||||
Mainly useful for shm, as the ringbuffer doesn't know the state
|
||||
of the connection.
|
||||
|
||||
2012-06-05 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
LOG: make it possible to fsync() on each file log.
|
||||
|
||||
2012-06-04 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: make sure that the created callback happens before dispatches
|
||||
This only happened on the socket ipc type.
|
||||
|
||||
LOG: fix the printing of %p in the blackbox
|
||||
|
||||
2012-06-01 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: On bsd's use the notifier for responses
|
||||
The point of this is to catch connection failures
|
||||
more reliably.
|
||||
|
||||
IPC: interpret ECONNRESET and EPIPE as ENOTCONN
|
||||
|
||||
2012-05-31 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
cleanup some warnings
|
||||
|
||||
config: use newer AC_COMPILE_IFELSE()
|
||||
|
||||
2012-05-28 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
blackbox: fix %p formatting
|
||||
|
||||
LOG: put all fields in the blackbox (added priority and tags)
|
||||
Fixes #36
|
||||
|
||||
example: make the priority uint8_t
|
||||
|
||||
Remove strerror out of check_funcs
|
||||
We only use strerror_r
|
||||
|
||||
RB: fix compiler warning.
|
||||
|
||||
Add replacement function stpcpy
|
||||
|
||||
Add missing AC_TYPE_UINT16_T to configure.ac
|
||||
|
||||
Use AC_FUNC_STRERROR_R and STRERROR_R_CHAR_P
|
||||
|
||||
Add stpcpy strcasecmp to the check_funcs
|
||||
|
||||
Move some conditional defines into code (from the configure script)
|
||||
|
||||
Remove some unused configure checks
|
||||
|
||||
Remove message queues
|
||||
|
||||
Check for union semun properly
|
||||
|
||||
Blackbox: provide more space for log messages when reading from the blackbox.
|
||||
This is to allow for the header (16bytes and variable length function).
|
||||
so if someone has a function name > 400 chars it will break. I
|
||||
recon that will do:)
|
||||
|
||||
2012-05-28 Andrew Beekhof <andrew@beekhof.net>
|
||||
|
||||
Add the blackbox reader manpage to the spec file
|
||||
|
||||
Enable error logging for the blackbox reader
|
||||
|
||||
RB: Read the file size into an initialized variable of the correct size
|
||||
|
||||
2012-05-28 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Add a tool to dump the blackbox.
|
||||
|
||||
2012-05-25 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
RB: to be safer save the read and write pointers at the top of the blackbox
|
||||
|
||||
2012-05-24 Jim Meyering <jim@meyering.net>
|
||||
|
||||
avoid unwarranted use of strncpy: use memcpy instead
|
||||
* lib/log_format.c (qb_vsnprintf_deserialize): We know that there are
|
||||
len or more non-NUL bytes in the source string, so it's clearer to
|
||||
use memcpy.
|
||||
|
||||
2012-05-24 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
blackbox: fix the print_from_file()
|
||||
|
||||
RB: add an option to not use any semaphores
|
||||
(brought over from the "speed" branch)
|
||||
|
||||
LOG: tweak the blackbox format string
|
||||
|
||||
LOG: accept NULL strings into the blackbox
|
||||
|
||||
LOG: protect close and reload from calling log
|
||||
Logging during these operations is temporarly disabled.
|
||||
|
||||
2012-05-21 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Add benchmark option (-b) to examples/ipcclient
|
||||
|
||||
TEST: make rbreader/writer more like the other benchmarking apps
|
||||
|
||||
2012-05-16 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: log the connection description in all logs
|
||||
|
||||
TEST: re-organise the ipc test suites
|
||||
|
||||
IPC: only modify the dispatch if we get EAGAIN
|
||||
|
||||
2012-05-12 Jan Friesse <jfriesse@redhat.com>
|
||||
|
||||
Correctly display timestamp in blackbox
|
||||
On little endian architectures where time_t is 64-bit long integer could
|
||||
happen, that instead of displaying correct timestamp, random data was
|
||||
used, because of memcpy.
|
||||
|
||||
Solution is to memcpy to real 32-bit variable and then assing this value
|
||||
to timestamp. This will let compiler decide endianity and store number
|
||||
correctly.
|
||||
|
||||
2012-05-10 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Add a more verbose version of the library versioning text.
|
||||
|
||||
Bump the library version to 0.13.0
|
||||
|
||||
Remove unneccessary __attribute__ ((aligned(8))) from internal headers
|
||||
|
||||
IPC: add a new function to get (and alloc) the extended stats.
|
||||
This should handle any further additions to the stats
|
||||
as the library allocs the struct.
|
||||
|
||||
Revert "Add the event queue length to the connection stats."
|
||||
This reverts commit 6b7da3f5315473c05b5939903d97be2e8ade4c8c.
|
||||
|
||||
IPC: cleanup better on a failed client connect.
|
||||
|
||||
IPC(soc): be more consistent with control struct size
|
||||
|
||||
IPC: kill a compiler warning
|
||||
|
||||
IPC(soc): pass in the correct size into munmap()
|
||||
|
||||
2012-05-10 The Quarterback Library Release Team <quarterback-devel@fedorahosted.org>
|
||||
|
||||
Bump the lib version to 0.12.0
|
||||
|
||||
2012-05-10 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
TEST: Use /bin/sh not /bin/bash
|
||||
|
||||
TEST: check for lost shared mem on bsd too
|
||||
|
||||
rb: cleanup the semaphores
|
||||
- the way they are selected
|
||||
- rpl_sem.c the error handling
|
||||
|
||||
Fix some small issues in ./check
|
||||
|
||||
2012-05-09 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Cleanup the .gitignore files
|
||||
|
||||
configure.ac tweaks
|
||||
Thanks again to Igor Pashev.
|
||||
|
||||
Remove HZ and use sysconf instead.
|
||||
|
||||
SUN_LEN() macro is present if __EXTENSIONS__ is defined on Illumos
|
||||
A bit reworked but originally from Igor Pashev:
|
||||
https://github.com/ip1981/libqb/commit/84c47f8160a9a78f068cc5b0d40b3901c065cfa2
|
||||
|
||||
Note: __EXTENSIONS__ also defines _GNU_SOURCE, so removing it as well.
|
||||
|
||||
2012-05-09 Igor Pashev <pashev.igor@gmail.com>
|
||||
|
||||
PF_UNIX is a POSIX standard name
|
||||
|
||||
Test for log facility names
|
||||
|
||||
2012-05-09 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: drop log message to debug.
|
||||
this can be noisy when there are a lot of transient
|
||||
connections.
|
||||
|
||||
2012-05-03 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: fix retrying of partial recv's and sends.
|
||||
Move to send() instead of sendmsg() as it's easier
|
||||
to track resending partial messages.
|
||||
|
||||
IPC: initialize enough shared mem for all 3 one way connections.
|
||||
|
||||
2012-05-02 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: keep retrying to recv the socket message if partially recv'ed (part 2)
|
||||
|
||||
IPC: keep retrying to recv the socket message if partially recv'ed
|
||||
|
||||
IPC: handle the server shutdown better
|
||||
|
||||
IPC: handle a connection disconnect from the server better
|
||||
Only problem with SOCKET.
|
||||
|
||||
2012-05-01 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: make it possible to send events in the connected callback.
|
||||
This was only a problem with QB_IPC_SOCKET.
|
||||
|
||||
Add the event queue length to the connection stats.
|
||||
|
||||
IPC: add a is_connected client side function.
|
||||
|
||||
Fix typo in ./check
|
||||
|
||||
docs: clarify the need to use request/response headers
|
||||
|
||||
Remove unused local variable
|
||||
|
||||
2012-04-30 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: change the socket recv function to read the response header.
|
||||
It needs to only recv the size of this message, else we recv more
|
||||
than one message and effectively drop messages (hidden at the end
|
||||
of the current message).
|
||||
|
||||
Add some special commands into the ipc example
|
||||
type "events" and the server will send 10 events.
|
||||
type 'kill' into the client and this will simulate the server dying.
|
||||
|
||||
TEST: improve the tracing in the ipc tests.
|
||||
|
||||
2012-04-30 Andrew Beekhof <andrew@beekhof.net>
|
||||
|
||||
Make "make (s)rpm" work more reliably
|
||||
Make sure the version number is re-calculated on each run.
|
||||
|
||||
2012-04-30 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
TEST: add a test to confirm we get the events we send.
|
||||
|
||||
TEST: reuse send_and_check for events.
|
||||
|
||||
IPC: make it possible for a root client to talk to a non-root server.
|
||||
|
||||
2012-04-26 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Run ./Lindent in the examples directory
|
||||
|
||||
Add some debug code to the ipcclient example
|
||||
|
||||
IPC: make sure ipc (socket) clients can connect to a server running as root.
|
||||
|
||||
2012-04-23 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
IPC: allow qb to bump the max_message_size
|
||||
I think this is more user friendly.
|
||||
|
||||
IPC: check for a sane minimum max_message_size
|
||||
|
||||
add rpl_sem.h loop_poll_int.h to noinst_headers
|
||||
|
||||
2012-04-04 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Handle errors more consistently
|
||||
|
||||
call recv_ready on socket types
|
||||
|
||||
Handle a recv of size 0
|
||||
|
||||
make bsd shm path better by default.
|
||||
|
||||
Fix kqueue on freebsd.
|
||||
|
||||
Get the example socket includes right.
|
||||
|
||||
Fix kqueue compiling.
|
||||
|
||||
POLL: seperate out the poll/epoll and add kqueue
|
||||
|
||||
2012-04-03 Jan Friesse <jfriesse@redhat.com>
|
||||
|
||||
Test existence of getpeer* functions
|
||||
|
||||
Add inet header to tcpclient example
|
||||
|
||||
Don't link with setpshared if unavailable
|
||||
|
||||
NetBSD doesn't have semun defined
|
||||
|
||||
2012-03-28 Jan Friesse <jfriesse@redhat.com>
|
||||
|
||||
Use MADV_NOSYNC only on systems where available
|
||||
|
||||
Use SCHED_BATCH only on platforms where available
|
||||
|
||||
2012-03-27 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Fix a bug introduced by the bsd patch.
|
||||
I missed the non-native case.
|
||||
|
||||
Cleanup the selection of semaphores to use
|
||||
|
||||
Fix some leaks in the logging.
|
||||
Mainly for valgrind purposes.
|
||||
|
||||
2012-03-24 Angus Salkeld <asalkeld@redhat.com>
|
||||
|
||||
Try and improve the portability on bsd variants.
|
||||
Also add a QB_IPC_NATIVE type that selects the best ipc type available.
|
||||
|
||||
2012-03-11 The Quarterback Library Release Team <quarterback-devel@fedorahosted.org>
|
||||
|
||||
Bump the version to 0.11.1
|
||||
|
||||
10
Makefile.am
10
Makefile.am
@ -41,7 +41,7 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
dist_doc_DATA = COPYING INSTALL README.markdown
|
||||
|
||||
SUBDIRS = include lib docs tests examples
|
||||
SUBDIRS = include lib docs tools tests examples
|
||||
|
||||
doxygen:
|
||||
$(MAKE) -C docs doxygen
|
||||
@ -107,12 +107,16 @@ RPMBUILDOPTS = --define "_sourcedir $(abs_builddir)" \
|
||||
--define "_srcrpmdir $(abs_builddir)" \
|
||||
--define "_rpmdir $(abs_builddir)"
|
||||
|
||||
tarball: $(TARFILE)
|
||||
|
||||
srpm: clean
|
||||
$(MAKE) $(SPEC) $(TARFILE)
|
||||
autoreconf -if
|
||||
$(MAKE) $(SPEC) tarball
|
||||
rpmbuild $(RPMBUILDOPTS) --nodeps -bs $(SPEC)
|
||||
|
||||
rpm: clean
|
||||
$(MAKE) $(SPEC) $(TARFILE)
|
||||
autoreconf -if
|
||||
$(MAKE) $(SPEC) tarball
|
||||
rpmbuild $(RPMBUILDOPTS) -ba $(SPEC)
|
||||
|
||||
# release/versioning
|
||||
|
||||
16
Makefile.in
16
Makefile.in
@ -58,8 +58,9 @@ host_triplet = @host@
|
||||
subdir = .
|
||||
DIST_COMMON = $(am__configure_deps) $(dist_doc_DATA) \
|
||||
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||
$(top_srcdir)/configure COPYING INSTALL compile config.guess \
|
||||
config.sub depcomp install-sh ltmain.sh missing
|
||||
$(top_srcdir)/configure COPYING INSTALL build-aux/compile \
|
||||
build-aux/config.guess build-aux/config.sub build-aux/depcomp \
|
||||
build-aux/install-sh build-aux/ltmain.sh build-aux/missing
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
@ -212,7 +213,6 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_RT = @LIB_RT@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
@ -315,7 +315,7 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure depcomp \
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
dist_doc_DATA = COPYING INSTALL README.markdown
|
||||
SUBDIRS = include lib docs tests examples
|
||||
SUBDIRS = include lib docs tools tests examples
|
||||
RPMBUILDOPTS = --define "_sourcedir $(abs_builddir)" \
|
||||
--define "_specdir $(abs_builddir)" \
|
||||
--define "_builddir $(abs_builddir)" \
|
||||
@ -910,12 +910,16 @@ $(SPEC): $(SPEC).in
|
||||
$(TARFILE):
|
||||
$(MAKE) dist
|
||||
|
||||
tarball: $(TARFILE)
|
||||
|
||||
srpm: clean
|
||||
$(MAKE) $(SPEC) $(TARFILE)
|
||||
autoreconf -if
|
||||
$(MAKE) $(SPEC) tarball
|
||||
rpmbuild $(RPMBUILDOPTS) --nodeps -bs $(SPEC)
|
||||
|
||||
rpm: clean
|
||||
$(MAKE) $(SPEC) $(TARFILE)
|
||||
autoreconf -if
|
||||
$(MAKE) $(SPEC) tarball
|
||||
rpmbuild $(RPMBUILDOPTS) -ba $(SPEC)
|
||||
.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
|
||||
0
config.guess → build-aux/config.guess
vendored
0
config.guess → build-aux/config.guess
vendored
0
config.sub → build-aux/config.sub
vendored
0
config.sub → build-aux/config.sub
vendored
159
configure.ac
159
configure.ac
@ -6,11 +6,14 @@ AC_PREREQ([2.61])
|
||||
AC_INIT([libqb],
|
||||
m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
[quarterback-devel@fedorahosted.org])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_SRCDIR([lib/ringbuffer.c])
|
||||
AC_CONFIG_HEADERS([include/config.h include/qb/qbconfig.h])
|
||||
AM_INIT_AUTOMAKE([-Wno-portability dist-xz color-tests parallel-tests])
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wno-portability dist-xz])
|
||||
dnl automake >= 1.11 offers --enable-silent-rules for suppressing the output from
|
||||
dnl normal compilation. When a failure occurs, it will then display the full
|
||||
dnl normal compilation. When a failure occurs, it will then display the full
|
||||
dnl command line
|
||||
dnl Wrap in m4_ifdef to avoid breaking on older platforms
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
@ -18,6 +21,7 @@ LT_PREREQ([2.2.6])
|
||||
LT_INIT
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_PROG_LIBTOOL
|
||||
AC_LANG([C])
|
||||
@ -73,11 +77,13 @@ AM_CONDITIONAL(HAVE_SPLINT, test -n "${SPLINT}")
|
||||
# this function checks if CC support options passed as
|
||||
# args. Global CFLAGS are ignored during this test.
|
||||
cc_supports_flag() {
|
||||
local CPPFLAGS="$CPPFLAGS $@"
|
||||
BACKUP="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $@"
|
||||
AC_MSG_CHECKING([whether $CC supports "$@"])
|
||||
AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])],
|
||||
[RC=0; AC_MSG_RESULT([yes])],
|
||||
[RC=1; AC_MSG_RESULT([no])])
|
||||
CPPFLAGS="$BACKUP"
|
||||
return $RC
|
||||
}
|
||||
|
||||
@ -94,10 +100,15 @@ case $exec_prefix in
|
||||
esac
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([rt], [mq_open])
|
||||
AC_CHECK_LIB([dl], [dlopen])
|
||||
AC_CHECK_LIB([pthread], [pthread_create])
|
||||
AC_CHECK_LIB([socket], [socket])
|
||||
dnl librt from glibc NEEDs libpthread
|
||||
dnl so. if test for libpthread after librt
|
||||
dnl it will always be "none needed", but it is not true
|
||||
dnl when linking libraries. Looks like a bug.
|
||||
AC_SEARCH_LIBS([pthread_create], [pthread])
|
||||
AC_SEARCH_LIBS([mq_open], [rt])
|
||||
AC_SEARCH_LIBS([dlopen], [dl])
|
||||
AC_SEARCH_LIBS([socket], [socket])
|
||||
AC_SEARCH_LIBS([gethostbyname], [nsl])
|
||||
|
||||
# look for testing harness "check"
|
||||
PKG_CHECK_MODULES([CHECK], [check >= 0.9.4],[with_check=yes],[with_check=no])
|
||||
@ -116,11 +127,13 @@ fi
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
|
||||
AC_CHECK_HEADERS([arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h stdint.h \
|
||||
dlfcn.h time.h sys/time.h stdlib.h string.h strings.h sys/types.h sys/stat.h \
|
||||
sys/param.h sys/socket.h sys/time.h sys/poll.h sys/epoll.h sys/uio.h \
|
||||
sys/sockio.h sys/un.h sys/resource.h syslog.h errno.h unistd.h sys/mman.h \
|
||||
sys/sem.h sys/ipc.h sys/msg.h mqueue.h])
|
||||
AC_CHECK_HEADERS([arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h \
|
||||
stdint.h stddef.h stdlib.h string.h strings.h \
|
||||
dlfcn.h time.h sys/time.h sys/types.h sys/stat.h \
|
||||
sys/param.h sys/socket.h sys/time.h sys/poll.h sys/epoll.h \
|
||||
sys/uio.h sys/event.h sys/sockio.h sys/un.h sys/resource.h \
|
||||
syslog.h errno.h unistd.h sys/mman.h \
|
||||
sys/sem.h sys/ipc.h sys/msg.h netdb.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_TYPE_UID_T
|
||||
@ -132,19 +145,59 @@ AC_TYPE_MODE_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT16_T
|
||||
AC_TYPE_UINT8_T
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
|
||||
[AC_DEFINE([HAVE_STRUCT_SOCKADDR_UN_SUN_LEN],
|
||||
1,
|
||||
[Define to 1 if struct sockaddr_un has a member sun_len])],
|
||||
[],
|
||||
[#include <sys/un.h>])
|
||||
|
||||
AC_MSG_CHECKING(looking for union semun in sys/sem.h)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>]],
|
||||
[[union semun arg; semctl(0, 0, 0, arg);]])],
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE_UNQUOTED([HAVE_SEMUN], 1, [Define to 1 if you have union semun.])
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([no])
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_CHOWN
|
||||
AC_FUNC_FORK
|
||||
AC_FUNC_MMAP
|
||||
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday localtime localtime_r \
|
||||
memset munmap socket strchr strrchr strdup strerror strstr \
|
||||
poll epoll_create epoll_create1 random rand getrlimit sysconf \
|
||||
AC_FUNC_STRERROR_R
|
||||
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday \
|
||||
localtime localtime_r memset munmap socket \
|
||||
strchr strrchr strdup strstr strcasecmp \
|
||||
poll epoll_create epoll_create1 kqueue \
|
||||
random rand getrlimit sysconf \
|
||||
pthread_spin_lock pthread_setschedparam \
|
||||
sched_get_priority_max sched_setscheduler])
|
||||
pthread_mutexattr_setpshared \
|
||||
pthread_condattr_setpshared \
|
||||
sem_timedwait semtimedop \
|
||||
sched_get_priority_max sched_setscheduler \
|
||||
getpeerucred getpeereid])
|
||||
|
||||
AM_CONDITIONAL(HAVE_SEM_TIMEDWAIT,
|
||||
[test "x$ac_cv_func_sem_timedwait" = xyes])
|
||||
AM_CONDITIONAL(HAVE_EPOLL,
|
||||
[test "x$ac_cv_func_epoll_create" = xyes])
|
||||
AM_CONDITIONAL(HAVE_POLL,
|
||||
[test "x$ac_cv_func_poll" = xyes])
|
||||
AM_CONDITIONAL(HAVE_KQUEUE,
|
||||
[test "x$ac_cv_func_kqueue" = xyes])
|
||||
|
||||
AC_CONFIG_LIBOBJ_DIR(lib)
|
||||
AC_REPLACE_FUNCS(strlcpy strlcat strchrnul)
|
||||
@ -152,9 +205,6 @@ AC_REPLACE_FUNCS(strlcpy strlcat strchrnul)
|
||||
## local defines
|
||||
PACKAGE_FEATURES=""
|
||||
|
||||
if test x$ac_cv_func_timerfd_create = xyes; then
|
||||
PACKAGE_FEATURES="$PACKAGE_FEATURES timerfd"
|
||||
fi
|
||||
if test x$ac_cv_func_epoll_create = xyes; then
|
||||
PACKAGE_FEATURES="$PACKAGE_FEATURES epoll"
|
||||
fi
|
||||
@ -209,9 +259,6 @@ fi
|
||||
# OS detection
|
||||
# THIS SECTION MUST DIE!
|
||||
CP=cp
|
||||
LIB_RT=-lrt
|
||||
supports_sysv_mq="yes"
|
||||
supports_posix_mq="yes"
|
||||
AC_MSG_CHECKING([for os in ${host_os}])
|
||||
case "$host_os" in
|
||||
*linux*)
|
||||
@ -219,22 +266,24 @@ case "$host_os" in
|
||||
[Compiling for Linux platform])
|
||||
AC_MSG_RESULT([Linux])
|
||||
;;
|
||||
*cygwin*)
|
||||
AC_DEFINE_UNQUOTED([QB_CYGWIN], [1],
|
||||
[Compiling for Cygwin platform])
|
||||
ac_cv_link_attribute_section=no
|
||||
nongcc_memory_barrier_needed=yes
|
||||
gcc_has_builtin_atomic_operations=no
|
||||
AC_MSG_RESULT([Cygwin])
|
||||
;;
|
||||
darwin*)
|
||||
AC_DEFINE_UNQUOTED([QB_DARWIN], [1],
|
||||
[Compiling for Darwin platform])
|
||||
CP=rsync
|
||||
LIB_RT=
|
||||
supports_sysv_mq="no"
|
||||
supports_posix_mq="no"
|
||||
ac_cv_link_attribute_section=no
|
||||
dnl Attribute section appears to work here but fails later with:
|
||||
dnl cc1: error in backend: Global variable 'descriptor.4902' has an invalid section specifier '__verbose': mach-o section specifier requires a segment and section separated by a comma
|
||||
AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON],
|
||||
[Shared memory define for Darwin platform])
|
||||
AC_DEFINE_UNQUOTED([PATH_MAX], [4096],
|
||||
[Number of chars in a path name including nul])
|
||||
AC_DEFINE_UNQUOTED([NAME_MAX], [255],
|
||||
[Number of chars in a file name])
|
||||
dnl cc1: error in backend: Global variable 'descriptor.4902'
|
||||
dnl has an invalid section specifier '__verbose': mach-o
|
||||
dnl section specifier requires a segment and section
|
||||
dnl separated by a comma
|
||||
AC_DEFINE_UNQUOTED([DISABLE_POSIX_THREAD_PROCESS_SHARED], [1],
|
||||
[Disable _POSIX_THREAD_PROCESS_SHARED])
|
||||
AC_MSG_RESULT([Dawin])
|
||||
@ -242,8 +291,6 @@ case "$host_os" in
|
||||
*bsd*)
|
||||
AC_DEFINE_UNQUOTED([QB_BSD], [1],
|
||||
[Compiling for BSD platform])
|
||||
AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON],
|
||||
[Shared memory define for Darwin platform])
|
||||
case "$host_os" in
|
||||
*freebsd[[234567]]*)
|
||||
;;
|
||||
@ -251,16 +298,26 @@ case "$host_os" in
|
||||
AC_DEFINE_UNQUOTED([QB_FREEBSD_GE_8], [1],
|
||||
[Compiling for FreeBSD >= 8 platform])
|
||||
;;
|
||||
*netbsd*)
|
||||
# this is because dlopen within a dl_iterate_phdr
|
||||
# callback locks up.
|
||||
ac_cv_link_attribute_section=no
|
||||
AC_DEFINE_UNQUOTED([UNIX_PATH_MAX], [103],
|
||||
[Unix path length])
|
||||
;;
|
||||
*openbsd*)
|
||||
AC_DEFINE_UNQUOTED([UNIX_PATH_MAX], [104],
|
||||
[Unix path length])
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([BSD])
|
||||
;;
|
||||
*solaris*)
|
||||
ac_cv_link_attribute_section=no
|
||||
AC_DEFINE_UNQUOTED(DISABLE_IPC_SHM, 1,
|
||||
[Disable shared mem ipc])
|
||||
AC_DEFINE_UNQUOTED([QB_SOLARIS], [1],
|
||||
[Compiling for Solaris platform])
|
||||
AC_DEFINE_UNQUOTED([TS_CLASS], [1],
|
||||
[Prevent being scheduled RR])
|
||||
AC_DEFINE_UNQUOTED([_SEM_SEMUN_UNDEFINED], [1],
|
||||
[The semun structure is undefined])
|
||||
CP=rsync
|
||||
AC_MSG_RESULT([Solaris])
|
||||
;;
|
||||
@ -345,7 +402,6 @@ AC_ARG_WITH([socket-dir],
|
||||
[ SOCKETDIR="$localstatedir/run" ])
|
||||
|
||||
AC_SUBST(CP)
|
||||
AC_SUBST(LIB_RT)
|
||||
# *FLAGS handling goes here
|
||||
|
||||
ENV_CFLAGS="$CFLAGS"
|
||||
@ -414,28 +470,6 @@ if test "x${enable_slow_tests}" = xyes ; then
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_SLOW_TESTS, [test "x${enable_slow_tests}" = xyes])
|
||||
|
||||
if test -n "$ac_cv_supports_sysv_mq"; then
|
||||
supports_sysv_mq=$ac_cv_supports_sysv_mq
|
||||
fi
|
||||
if test "x${supports_sysv_mq}" = xyes ; then
|
||||
AC_DEFINE([HAVE_SYSV_MQ], [1],
|
||||
[have sysv message queues])
|
||||
PACKAGE_FEATURES="$PACKAGE_FEATURES sysv_mq"
|
||||
AC_MSG_NOTICE([Enabling SYSV Message Queues])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_SYSV_MQ, [test "x${supports_sysv_mq}" = xyes])
|
||||
|
||||
if test -n "$ac_cv_supports_posix_mq"; then
|
||||
supports_posix_mq=$ac_cv_supports_posix_mq
|
||||
fi
|
||||
if test "x${supports_posix_mq}" = xyes ; then
|
||||
AC_DEFINE([HAVE_POSIX_MQ], [1],
|
||||
[have posix message queues])
|
||||
PACKAGE_FEATURES="$PACKAGE_FEATURES posix_mq"
|
||||
AC_MSG_NOTICE([Enabling POSIX Message Queues])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_POSIX_MQ, [test "x${supports_posix_mq}" = xyes])
|
||||
|
||||
# --- callsite sections ---
|
||||
if test "x${GCC}" = xyes; then
|
||||
AC_MSG_CHECKING([whether GCC supports __attribute__((section())])
|
||||
@ -504,6 +538,7 @@ AC_CONFIG_FILES([Makefile
|
||||
include/qb/Makefile
|
||||
lib/Makefile
|
||||
lib/libqb.pc
|
||||
tools/Makefile
|
||||
tests/Makefile
|
||||
examples/Makefile
|
||||
docs/Makefile
|
||||
|
||||
@ -27,7 +27,7 @@ dependant_headers = $(wildcard $(inc_dir)/qb*.h)
|
||||
dist_man_MANS = man3/qbipcc.h.3 man3/qbipcs.h.3 man3/qbatomic.h.3 \
|
||||
man3/qbhdb.h.3 man3/qbipc_common.h.3 man3/qblist.h.3 \
|
||||
man3/qbloop.h.3 man3/qbutil.h.3 man3/qbarray.h.3 \
|
||||
man3/qblog.h.3 man3/qbmap.h.3
|
||||
man3/qblog.h.3 man3/qbmap.h.3 man8/qb-blackbox.8
|
||||
|
||||
|
||||
$(dist_man_MANS): man.dox $(dependant_headers)
|
||||
|
||||
@ -105,7 +105,8 @@ am__uninstall_files_from_dir = { \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
man3dir = $(mandir)/man3
|
||||
am__installdirs = "$(DESTDIR)$(man3dir)"
|
||||
am__installdirs = "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man8dir)"
|
||||
man8dir = $(mandir)/man8
|
||||
NROFF = nroff
|
||||
MANS = $(dist_man_MANS)
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
@ -158,7 +159,6 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_RT = @LIB_RT@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
@ -253,7 +253,7 @@ noinst_HEADERS = mainpage.h
|
||||
@HAVE_DOXYGEN_TRUE@dist_man_MANS = man3/qbipcc.h.3 man3/qbipcs.h.3 man3/qbatomic.h.3 \
|
||||
@HAVE_DOXYGEN_TRUE@ man3/qbhdb.h.3 man3/qbipc_common.h.3 man3/qblist.h.3 \
|
||||
@HAVE_DOXYGEN_TRUE@ man3/qbloop.h.3 man3/qbutil.h.3 man3/qbarray.h.3 \
|
||||
@HAVE_DOXYGEN_TRUE@ man3/qblog.h.3 man3/qbmap.h.3
|
||||
@HAVE_DOXYGEN_TRUE@ man3/qblog.h.3 man3/qbmap.h.3 man8/qb-blackbox.8
|
||||
|
||||
all: all-am
|
||||
|
||||
@ -334,6 +334,42 @@ uninstall-man3:
|
||||
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
|
||||
dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir)
|
||||
install-man8: $(dist_man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
|
||||
@list=''; test -n "$(man8dir)" || exit 0; \
|
||||
{ for i in $$list; do echo "$$i"; done; \
|
||||
l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
|
||||
sed -n '/\.8[a-z]*$$/p'; \
|
||||
} | while read p; do \
|
||||
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; echo "$$p"; \
|
||||
done | \
|
||||
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
|
||||
sed 'N;N;s,\n, ,g' | { \
|
||||
list=; while read file base inst; do \
|
||||
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
|
||||
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
|
||||
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
|
||||
fi; \
|
||||
done; \
|
||||
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
|
||||
done; }
|
||||
|
||||
uninstall-man8:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list=''; test -n "$(man8dir)" || exit 0; \
|
||||
files=`{ for i in $$list; do echo "$$i"; done; \
|
||||
l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
|
||||
sed -n '/\.8[a-z]*$$/p'; \
|
||||
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
|
||||
dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
@ -434,7 +470,7 @@ check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(MANS) $(HEADERS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(man3dir)"; do \
|
||||
for dir in "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man8dir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
@ -502,7 +538,7 @@ install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man: install-man3
|
||||
install-man: install-man3 install-man8
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
@ -532,7 +568,7 @@ ps-am:
|
||||
|
||||
uninstall-am: uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man3
|
||||
uninstall-man: uninstall-man3 uninstall-man8
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
@ -542,12 +578,13 @@ uninstall-man: uninstall-man3
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-man3 install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-man uninstall-man3
|
||||
install-info-am install-man install-man3 install-man8 \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-man uninstall-man3 \
|
||||
uninstall-man8
|
||||
|
||||
|
||||
@HAVE_DOXYGEN_TRUE@$(dist_man_MANS): man.dox $(dependant_headers)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = libqb
|
||||
PROJECT_NUMBER = 0.11.1
|
||||
PROJECT_NUMBER = 0.14.2
|
||||
OUTPUT_DIRECTORY = .
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
|
||||
@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
|
||||
@ -3,11 +3,13 @@
|
||||
*
|
||||
* @section overview Overview
|
||||
*
|
||||
* libqb is a thread-safe library with the primary purpose of providing high performance client server reusable features.
|
||||
* libqb is a thread-safe library with the primary purpose of providing high
|
||||
* performance client server reusable features.
|
||||
*
|
||||
* It provides high performance ipc, and poll.
|
||||
*
|
||||
* We don't intend be an all encompassing library, but instead provide very specially focused APIs that are highly
|
||||
* We don't intend be an all encompassing library, but instead provide very
|
||||
* specially focused APIs that are highly
|
||||
*
|
||||
* tuned for maximum performance for client/server applications.
|
||||
*
|
||||
@ -74,8 +76,6 @@
|
||||
* and service applications. It supports many features including:
|
||||
* - Multiple transport implementations
|
||||
* -# Shared memory implementation for very high performance.
|
||||
* -# Posix Message queues
|
||||
* -# SysV Message queues
|
||||
* -# Unix sockets
|
||||
* - A synchronous request/response channel and asynchronous response channel per ipc connection.
|
||||
* - User defined private data per IPC connection.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = libqb
|
||||
PROJECT_NUMBER = 0.11.1
|
||||
PROJECT_NUMBER = 0.14.2
|
||||
OUTPUT_DIRECTORY = .
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
|
||||
@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbarray.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbarray.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -62,13 +62,13 @@ This is a dynamic array (it can grow, but without moving memory)\&.
|
||||
|
||||
.PP
|
||||
.nf
|
||||
arr = qb_array_create_2(64, sizeof(struct my_struct), 256);
|
||||
\&.\&.\&.
|
||||
res = qb_array_index(arr, idx, (void**)&my_ptr);
|
||||
if (res < 0) {
|
||||
arr = qb_array_create_2(64, sizeof(struct my_struct), 256);
|
||||
\&.\&.\&.
|
||||
res = qb_array_index(arr, idx, (void**)&my_ptr);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
// use my_ptr, now even if there is a grow, this pointer will be valid\&.
|
||||
}
|
||||
// use my_ptr, now even if there is a grow, this pointer will be valid\&.
|
||||
.fi
|
||||
.PP
|
||||
|
||||
@ -80,7 +80,7 @@ This is a dynamic array (it can grow, but without moving memory)\&.
|
||||
This is an opaque data type representing an instance of an array\&.
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "\fBqb_array_t\fP* \fBqb_array_create\fP (size_tmax_elements, size_telement_size)"
|
||||
.SS "\fBqb_array_t\fP* qb_array_create (size_tmax_elements, size_telement_size)"
|
||||
|
||||
.PP
|
||||
Create an array with fixed sized elements\&. \fBParameters:\fP
|
||||
@ -96,7 +96,7 @@ array instance\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "\fBqb_array_t\fP* \fBqb_array_create_2\fP (size_tmax_elements, size_telement_size, size_tautogrow_elements)"
|
||||
.SS "\fBqb_array_t\fP* qb_array_create_2 (size_tmax_elements, size_telement_size, size_tautogrow_elements)"
|
||||
|
||||
.PP
|
||||
Create an array with fixed sized elements\&. \fBParameters:\fP
|
||||
@ -114,11 +114,11 @@ array instance\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "size_t \fBqb_array_elems_per_bin_get\fP (\fBqb_array_t\fP *a)"
|
||||
.SS "size_t qb_array_elems_per_bin_get (\fBqb_array_t\fP *a)"
|
||||
|
||||
.PP
|
||||
Get the number of elements per bin\&.
|
||||
.SS "void \fBqb_array_free\fP (\fBqb_array_t\fP *a)"
|
||||
.SS "void qb_array_free (\fBqb_array_t\fP *a)"
|
||||
|
||||
.PP
|
||||
Free all the memory used by the array\&. \fBParameters:\fP
|
||||
@ -127,7 +127,7 @@ Free all the memory used by the array\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_array_grow\fP (\fBqb_array_t\fP *a, size_tmax_elements)"
|
||||
.SS "int32_t qb_array_grow (\fBqb_array_t\fP *a, size_tmax_elements)"
|
||||
|
||||
.PP
|
||||
Grow the array\&. \fBParameters:\fP
|
||||
@ -143,7 +143,7 @@ Grow the array\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_array_index\fP (\fBqb_array_t\fP *a, int32_tidx, void **element_out)"
|
||||
.SS "int32_t qb_array_index (\fBqb_array_t\fP *a, int32_tidx, void **element_out)"
|
||||
|
||||
.PP
|
||||
Get an element at a particular index\&. \fBParameters:\fP
|
||||
@ -161,7 +161,7 @@ Get an element at a particular index\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "size_t \fBqb_array_num_bins_get\fP (\fBqb_array_t\fP *a)"
|
||||
.SS "size_t qb_array_num_bins_get (\fBqb_array_t\fP *a)"
|
||||
|
||||
.PP
|
||||
Get the number of bins used or the array\&.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbatomic.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbatomic.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -16,7 +16,7 @@ Basic atomic integer and pointer operations\&.
|
||||
\fC#include <qb/qbconfig\&.h>\fP
|
||||
.br
|
||||
|
||||
.SS "Defines"
|
||||
.SS "Macros"
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
@ -92,9 +92,9 @@ You must not directly read integers or pointers concurrently accessed by multipl
|
||||
If you are using those functions for anything apart from simple reference counting, you should really be aware of the implications of doing that\&. There are literally thousands of ways to shoot yourself in the foot\&. So if in doubt, use a pthread_mutex\&. If you don't know, what memory barriers are, do not use anything but \fBqb_atomic_int_inc()\fP and \fBqb_atomic_int_dec_and_test()\fP\&.
|
||||
.PP
|
||||
It is not safe to set an integer or pointer just by assigning to it, when it is concurrently accessed by other threads with the following functions\&. Use \fBqb_atomic_int_compare_and_exchange()\fP or \fBqb_atomic_pointer_compare_and_exchange()\fP respectively\&.
|
||||
.SH "Define Documentation"
|
||||
.SH "Macro Definition Documentation"
|
||||
.PP
|
||||
.SS "#define \fBqb_atomic_int_dec_and_test\fP(atomic) (\fBqb_atomic_int_exchange_and_add\fP ((atomic), -1) == 1)"
|
||||
.SS "#define qb_atomic_int_dec_and_test(atomic) (\fBqb_atomic_int_exchange_and_add\fP ((atomic), -1) == 1)"
|
||||
|
||||
.PP
|
||||
Atomically decrements the integer pointed to by atomic by 1\&. \fBParameters:\fP
|
||||
@ -108,14 +108,14 @@ QB_TRUE if the integer pointed to by atomic is 0 after decrementing it
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_atomic_int_get\fP(atomic)"
|
||||
.SS "#define qb_atomic_int_get(atomic)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
((void) sizeof (char* [sizeof (*(atomic)) == sizeof (int32_t) ? 1 : -1]), \
|
||||
(qb_atomic_int_get) ((volatile int32_t QB_GNUC_MAY_ALIAS *) (volatile void *) (atomic)))
|
||||
.fi
|
||||
.SS "#define \fBqb_atomic_int_inc\fP(atomic) (\fBqb_atomic_int_add\fP ((atomic), 1))"
|
||||
.SS "#define qb_atomic_int_inc(atomic) (\fBqb_atomic_int_add\fP ((atomic), 1))"
|
||||
|
||||
.PP
|
||||
Atomically increments the integer pointed to by atomic by 1\&. \fBParameters:\fP
|
||||
@ -124,21 +124,21 @@ Atomically increments the integer pointed to by atomic by 1\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_atomic_int_set\fP(atomic, newval)"
|
||||
.SS "#define qb_atomic_int_set(atomic, newval)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
((void) sizeof (char* [sizeof (*(atomic)) == sizeof (int32_t) ? 1 : -1]), \
|
||||
(qb_atomic_int_set) ((volatile int32_t QB_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (newval)))
|
||||
.fi
|
||||
.SS "#define \fBqb_atomic_pointer_get\fP(atomic)"
|
||||
.SS "#define qb_atomic_pointer_get(atomic)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
((void) sizeof (char* [sizeof (*(atomic)) == sizeof (void*) ? 1 : -1]), \
|
||||
(qb_atomic_pointer_get) ((volatile void* QB_GNUC_MAY_ALIAS *) (volatile void *) (atomic)))
|
||||
.fi
|
||||
.SS "#define \fBqb_atomic_pointer_set\fP(atomic, newval)"
|
||||
.SS "#define qb_atomic_pointer_set(atomic, newval)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -147,9 +147,9 @@ Atomically increments the integer pointed to by atomic by 1\&. \fBParameters:\fP
|
||||
.fi
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "void \fBqb_atomic_init\fP (void)"
|
||||
.SS "void qb_atomic_init (void)"
|
||||
|
||||
.SS "void \fBqb_atomic_int_add\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)"
|
||||
.SS "void qb_atomic_int_add (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)"
|
||||
|
||||
.PP
|
||||
Atomically adds val to the integer pointed to by atomic\&. Also acts as a memory barrier\&.
|
||||
@ -162,7 +162,7 @@ Atomically adds val to the integer pointed to by atomic\&. Also acts as a memory
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_atomic_int_compare_and_exchange\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_toldval, int32_tnewval)"
|
||||
.SS "int32_t qb_atomic_int_compare_and_exchange (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_toldval, int32_tnewval)"
|
||||
|
||||
.PP
|
||||
Compares oldval with the integer pointed to by atomic and if they are equal, atomically exchanges *atomic with newval\&. Also acts as a memory barrier\&.
|
||||
@ -182,7 +182,7 @@ QB_TRUE, if *atomic was equal oldval\&. QB_FALSE otherwise\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_atomic_int_exchange_and_add\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)"
|
||||
.SS "int32_t qb_atomic_int_exchange_and_add (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)"
|
||||
|
||||
.PP
|
||||
Atomically adds val to the integer pointed to by atomic\&. It returns the value of *atomic just before the addition took place\&. Also acts as a memory barrier\&.
|
||||
@ -200,7 +200,7 @@ the value of *atomic before the addition\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_atomic_int_get\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic)"
|
||||
.SS "int32_t qb_atomic_int_get (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic)"
|
||||
|
||||
.PP
|
||||
Reads the value of the integer pointed to by atomic\&. Also acts as a memory barrier\&.
|
||||
@ -216,7 +216,7 @@ the value of atomic
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_atomic_int_set\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tnewval)"
|
||||
.SS "void qb_atomic_int_set (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tnewval)"
|
||||
|
||||
.PP
|
||||
Sets the value of the integer pointed to by atomic\&. Also acts as a memory barrier\&.
|
||||
@ -229,7 +229,7 @@ Sets the value of the integer pointed to by atomic\&. Also acts as a memory barr
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_atomic_pointer_compare_and_exchange\fP (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *oldval, void *newval)"
|
||||
.SS "int32_t qb_atomic_pointer_compare_and_exchange (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *oldval, void *newval)"
|
||||
|
||||
.PP
|
||||
Compares oldval with the pointer pointed to by atomic and if they are equal, atomically exchanges *atomic with newval\&. Also acts as a memory barrier\&.
|
||||
@ -249,7 +249,7 @@ QB_TRUE if atomic was equal oldval, else QB_FALSE\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void* \fBqb_atomic_pointer_get\fP (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic)"
|
||||
.SS "void* qb_atomic_pointer_get (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic)"
|
||||
|
||||
.PP
|
||||
Reads the value of the pointer pointed to by atomic\&. Also acts as a memory barrier\&.
|
||||
@ -265,7 +265,7 @@ the value to add to atomic\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_atomic_pointer_set\fP (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *newval)"
|
||||
.SS "void qb_atomic_pointer_set (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *newval)"
|
||||
|
||||
.PP
|
||||
Sets the value of the pointer pointed to by atomic\&. Also acts as a memory barrier\&.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbhdb.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbhdb.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -28,7 +28,7 @@ The handle database is for reference counting objects\&.
|
||||
.RI "struct \fBqb_hdb\fP"
|
||||
.br
|
||||
.in -1c
|
||||
.SS "Defines"
|
||||
.SS "Macros"
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
@ -108,13 +108,13 @@ The handle database is for reference counting objects\&.
|
||||
The handle database is for reference counting objects\&.
|
||||
|
||||
|
||||
.SH "Define Documentation"
|
||||
.SH "Macro Definition Documentation"
|
||||
.PP
|
||||
.SS "#define \fB_GNU_SOURCE\fP"
|
||||
.SS "#define _GNU_SOURCE"
|
||||
|
||||
.SS "#define \fBQB_HDB_D_FORMAT\fP '%'PRIu64"
|
||||
.SS "#define QB_HDB_D_FORMAT '%'PRIu64"
|
||||
|
||||
.SS "#define \fBQB_HDB_DECLARE\fP(database_name, destructor_function)"
|
||||
.SS "#define QB_HDB_DECLARE(database_name, destructor_function)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -129,11 +129,11 @@ static struct qb_hdb (database_name) = { \
|
||||
.PP
|
||||
Convience macro for declaring a file scoped handle database\&. .PP
|
||||
.nf
|
||||
QB_HDB_DECLARE(my_handle_database, NULL);
|
||||
QB_HDB_DECLARE(my_handle_database, NULL);
|
||||
.fi
|
||||
.PP
|
||||
|
||||
.SS "#define \fBQB_HDB_X_FORMAT\fP '%'PRIx64"
|
||||
.SS "#define QB_HDB_X_FORMAT '%'PRIx64"
|
||||
|
||||
.SH "Typedef Documentation"
|
||||
.PP
|
||||
@ -143,9 +143,9 @@ Convience macro for declaring a file scoped handle database\&. .PP
|
||||
Generic handle type is 64 bits\&.
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "uint32_t \fBqb_hdb_base_convert\fP (\fBqb_handle_t\fPhandle)"
|
||||
.SS "uint32_t qb_hdb_base_convert (\fBqb_handle_t\fPhandle)"
|
||||
|
||||
.SS "void \fBqb_hdb_create\fP (struct \fBqb_hdb\fP *hdb)"
|
||||
.SS "void qb_hdb_create (struct \fBqb_hdb\fP *hdb)"
|
||||
|
||||
.PP
|
||||
Create a new database\&. \fBParameters:\fP
|
||||
@ -154,7 +154,7 @@ Create a new database\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_hdb_destroy\fP (struct \fBqb_hdb\fP *hdb)"
|
||||
.SS "void qb_hdb_destroy (struct \fBqb_hdb\fP *hdb)"
|
||||
|
||||
.PP
|
||||
Destroy a handle database\&. \fBParameters:\fP
|
||||
@ -163,7 +163,7 @@ Destroy a handle database\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_hdb_handle_create\fP (struct \fBqb_hdb\fP *hdb, int32_tinstance_size, \fBqb_handle_t\fP *handle_id_out)"
|
||||
.SS "int32_t qb_hdb_handle_create (struct \fBqb_hdb\fP *hdb, int32_tinstance_size, \fBqb_handle_t\fP *handle_id_out)"
|
||||
|
||||
.PP
|
||||
Create a new handle\&. \fBParameters:\fP
|
||||
@ -181,7 +181,7 @@ Create a new handle\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_hdb_handle_destroy\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)"
|
||||
.SS "int32_t qb_hdb_handle_destroy (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)"
|
||||
|
||||
.PP
|
||||
Request the destruction of the object\&. When the refcount is 0, it will be destroyed\&.
|
||||
@ -199,7 +199,7 @@ Request the destruction of the object\&. When the refcount is 0, it will be dest
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_hdb_handle_get\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)"
|
||||
.SS "int32_t qb_hdb_handle_get (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)"
|
||||
|
||||
.PP
|
||||
Get the instance associated with this handle and increase it's refcount\&. \fBParameters:\fP
|
||||
@ -217,7 +217,7 @@ Get the instance associated with this handle and increase it's refcount\&. \fBPa
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_hdb_handle_get_always\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)"
|
||||
.SS "int32_t qb_hdb_handle_get_always (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)"
|
||||
|
||||
.PP
|
||||
Get the instance associated with this handle and increase it's refcount\&. \fBParameters:\fP
|
||||
@ -235,7 +235,7 @@ Get the instance associated with this handle and increase it's refcount\&. \fBPa
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_hdb_handle_put\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)"
|
||||
.SS "int32_t qb_hdb_handle_put (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)"
|
||||
|
||||
.PP
|
||||
Put the instance associated with this handle and decrease it's refcount\&. \fBParameters:\fP
|
||||
@ -251,7 +251,7 @@ Put the instance associated with this handle and decrease it's refcount\&. \fBPa
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_hdb_handle_refcount_get\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)"
|
||||
.SS "int32_t qb_hdb_handle_refcount_get (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)"
|
||||
|
||||
.PP
|
||||
Get the current refcount\&. \fBParameters:\fP
|
||||
@ -267,7 +267,7 @@ Get the current refcount\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_hdb_iterator_next\fP (struct \fBqb_hdb\fP *hdb, void **instance, \fBqb_handle_t\fP *handle)"
|
||||
.SS "int32_t qb_hdb_iterator_next (struct \fBqb_hdb\fP *hdb, void **instance, \fBqb_handle_t\fP *handle)"
|
||||
|
||||
.PP
|
||||
Get the next object and increament it's refcount\&. Remember to call \fBqb_hdb_handle_put()\fP
|
||||
@ -287,7 +287,7 @@ Get the next object and increament it's refcount\&. Remember to call \fBqb_hdb_h
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_hdb_iterator_reset\fP (struct \fBqb_hdb\fP *hdb)"
|
||||
.SS "void qb_hdb_iterator_reset (struct \fBqb_hdb\fP *hdb)"
|
||||
|
||||
.PP
|
||||
Reset the iterator\&. \fBParameters:\fP
|
||||
@ -296,7 +296,7 @@ Reset the iterator\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "uint64_t \fBqb_hdb_nocheck_convert\fP (uint32_thandle)"
|
||||
.SS "uint64_t qb_hdb_nocheck_convert (uint32_thandle)"
|
||||
|
||||
.SH "Author"
|
||||
.PP
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbipc_common.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbipc_common.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -19,7 +19,7 @@ qbipc_common.h \-
|
||||
.RI "struct \fBqb_ipc_response_header\fP"
|
||||
.br
|
||||
.in -1c
|
||||
.SS "Defines"
|
||||
.SS "Macros"
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
@ -42,7 +42,7 @@ qbipc_common.h \-
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
.RI "enum \fBqb_ipc_type\fP { \fBQB_IPC_SOCKET\fP, \fBQB_IPC_SHM\fP, \fBQB_IPC_POSIX_MQ\fP, \fBQB_IPC_SYSV_MQ\fP }"
|
||||
.RI "enum \fBqb_ipc_type\fP { \fBQB_IPC_SOCKET\fP, \fBQB_IPC_SHM\fP, \fBQB_IPC_POSIX_MQ\fP, \fBQB_IPC_SYSV_MQ\fP, \fBQB_IPC_NATIVE\fP }"
|
||||
.br
|
||||
.in -1c
|
||||
.SS "Functions"
|
||||
@ -59,17 +59,17 @@ qbipc_common.h \-
|
||||
.RI "enum \fBqb_ipc_type\fP \fB__attribute__\fP"
|
||||
.br
|
||||
.in -1c
|
||||
.SH "Define Documentation"
|
||||
.SH "Macro Definition Documentation"
|
||||
.PP
|
||||
.SS "#define \fBQB_IPC_MSG_AUTHENTICATE\fP -1"
|
||||
.SS "#define QB_IPC_MSG_AUTHENTICATE -1"
|
||||
|
||||
.SS "#define \fBQB_IPC_MSG_DISCONNECT\fP -3"
|
||||
.SS "#define QB_IPC_MSG_DISCONNECT -3"
|
||||
|
||||
.SS "#define \fBQB_IPC_MSG_NEW_EVENT_SOCK\fP -2"
|
||||
.SS "#define QB_IPC_MSG_NEW_EVENT_SOCK -2"
|
||||
|
||||
.SS "#define \fBQB_IPC_MSG_NEW_MESSAGE\fP 0"
|
||||
.SS "#define QB_IPC_MSG_NEW_MESSAGE 0"
|
||||
|
||||
.SS "#define \fBQB_IPC_MSG_USER_START\fP \fBQB_IPC_MSG_NEW_MESSAGE\fP"
|
||||
.SS "#define QB_IPC_MSG_USER_START \fBQB_IPC_MSG_NEW_MESSAGE\fP"
|
||||
|
||||
.SH "Enumeration Type Documentation"
|
||||
.PP
|
||||
@ -86,14 +86,16 @@ qbipc_common.h \-
|
||||
\fB\fIQB_IPC_POSIX_MQ \fP\fP
|
||||
.TP
|
||||
\fB\fIQB_IPC_SYSV_MQ \fP\fP
|
||||
.TP
|
||||
\fB\fIQB_IPC_NATIVE \fP\fP
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "struct \fBqb_ipc_request_header\fP \fB__attribute__\fP ((aligned(8)))"
|
||||
.SS "struct \fBqb_ipc_request_header\fP __attribute__ ((aligned(8)))"
|
||||
|
||||
.SH "Variable Documentation"
|
||||
.PP
|
||||
.SS "int32_t error \fB__attribute__\fP"
|
||||
.SS "int32_t error __attribute__"
|
||||
|
||||
.SH "Author"
|
||||
.PP
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbipcc.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbipcc.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -76,6 +76,10 @@ Client IPC API\&.
|
||||
.RI "void * \fBqb_ipcc_context_get\fP (\fBqb_ipcc_connection_t\fP *c)"
|
||||
.br
|
||||
.RI "\fIGet the context (set previously) \fP"
|
||||
.ti -1c
|
||||
.RI "int32_t \fBqb_ipcc_is_connected\fP (\fBqb_ipcc_connection_t\fP *c)"
|
||||
.br
|
||||
.RI "\fIIs the connection connected? \fP"
|
||||
.in -1c
|
||||
.SH "Detailed Description"
|
||||
.PP
|
||||
@ -108,7 +112,7 @@ The \fBqb_ipcc_event_recv()\fP function receives an out-of-band asyncronous mess
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "\fBqb_ipcc_connection_t\fP* \fBqb_ipcc_connect\fP (const char *name, size_tmax_msg_size)"
|
||||
.SS "\fBqb_ipcc_connection_t\fP* qb_ipcc_connect (const char *name, size_tmax_msg_size)"
|
||||
|
||||
.PP
|
||||
Create a connection to an IPC service\&. \fBParameters:\fP
|
||||
@ -124,7 +128,7 @@ NULL (error: see errno) or a connection object\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void* \fBqb_ipcc_context_get\fP (\fBqb_ipcc_connection_t\fP *c)"
|
||||
.SS "void* qb_ipcc_context_get (\fBqb_ipcc_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Get the context (set previously) \fBParameters:\fP
|
||||
@ -143,7 +147,7 @@ the context
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcc_context_set\fP (\fBqb_ipcc_connection_t\fP *c, void *context)"
|
||||
.SS "void qb_ipcc_context_set (\fBqb_ipcc_connection_t\fP *c, void *context)"
|
||||
|
||||
.PP
|
||||
Associate a 'user' pointer with this connection\&. \fBParameters:\fP
|
||||
@ -159,7 +163,7 @@ Associate a 'user' pointer with this connection\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcc_disconnect\fP (\fBqb_ipcc_connection_t\fP *c)"
|
||||
.SS "void qb_ipcc_disconnect (\fBqb_ipcc_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Disconnect an IPC connection\&. \fBParameters:\fP
|
||||
@ -168,7 +172,7 @@ Disconnect an IPC connection\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcc_event_recv\fP (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)"
|
||||
.SS "ssize_t qb_ipcc_event_recv (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)"
|
||||
|
||||
.PP
|
||||
Receive an event\&. \fBParameters:\fP
|
||||
@ -186,11 +190,16 @@ Receive an event\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
size of the message or error (-errno)
|
||||
size of the message or error (-errno)
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
that msg_ptr will include a \fBqb_ipc_response_header\fP at the top of the message\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_ipcc_fc_enable_max_set\fP (\fBqb_ipcc_connection_t\fP *c, uint32_tmax)"
|
||||
.SS "int32_t qb_ipcc_fc_enable_max_set (\fBqb_ipcc_connection_t\fP *c, uint32_tmax)"
|
||||
|
||||
.PP
|
||||
Set the maximum allowable flowcontrol value\&. \fBNote:\fP
|
||||
@ -206,7 +215,7 @@ the default is 1
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_ipcc_fd_get\fP (\fBqb_ipcc_connection_t\fP *c, int32_t *fd)"
|
||||
.SS "int32_t qb_ipcc_fd_get (\fBqb_ipcc_connection_t\fP *c, int32_t *fd)"
|
||||
|
||||
.PP
|
||||
Get the file descriptor to poll\&. \fBParameters:\fP
|
||||
@ -217,7 +226,23 @@ Get the file descriptor to poll\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcc_recv\fP (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)"
|
||||
.SS "int32_t qb_ipcc_is_connected (\fBqb_ipcc_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Is the connection connected? \fBParameters:\fP
|
||||
.RS 4
|
||||
\fIc\fP connection instance
|
||||
.RE
|
||||
.PP
|
||||
\fBReturn values:\fP
|
||||
.RS 4
|
||||
\fIQB_TRUE\fP when connected
|
||||
.br
|
||||
\fIQB_FALSE\fP when not connected
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t qb_ipcc_recv (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)"
|
||||
|
||||
.PP
|
||||
Receive a response\&. \fBParameters:\fP
|
||||
@ -233,11 +258,16 @@ Receive a response\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
(size recv'ed, -errno == error)
|
||||
(size recv'ed, -errno == error)
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
that msg_ptr will include a \fBqb_ipc_response_header\fP at the top of the message\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcc_send\fP (\fBqb_ipcc_connection_t\fP *c, const void *msg_ptr, size_tmsg_len)"
|
||||
.SS "ssize_t qb_ipcc_send (\fBqb_ipcc_connection_t\fP *c, const void *msg_ptr, size_tmsg_len)"
|
||||
|
||||
.PP
|
||||
Send a message\&. \fBParameters:\fP
|
||||
@ -251,11 +281,16 @@ Send a message\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
(size sent, -errno == error)
|
||||
(size sent, -errno == error)
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
the msg_ptr must include a \fBqb_ipc_request_header\fP at the top of the message\&. The server will read the size field to determine how much to recv\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcc_sendv\fP (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, size_tiov_len)"
|
||||
.SS "ssize_t qb_ipcc_sendv (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, size_tiov_len)"
|
||||
|
||||
.PP
|
||||
Send a message (iovec)\&. \fBParameters:\fP
|
||||
@ -269,11 +304,16 @@ Send a message (iovec)\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
(size sent, -errno == error)
|
||||
(size sent, -errno == error)
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
the iov[0] must be a \fBqb_ipc_request_header\fP\&. The server will read the size field to determine how much to recv\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcc_sendv_recv\fP (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, uint32_tiov_len, void *msg_ptr, size_tmsg_len, int32_tms_timeout)"
|
||||
.SS "ssize_t qb_ipcc_sendv_recv (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, uint32_tiov_len, void *msg_ptr, size_tmsg_len, int32_tms_timeout)"
|
||||
|
||||
.PP
|
||||
This is a convenience function that simply sends and then recvs\&. \fBParameters:\fP
|
||||
@ -291,6 +331,13 @@ This is a convenience function that simply sends and then recvs\&. \fBParameters
|
||||
\fIms_timeout\fP max time to wait for a response
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
the iov[0] must include a \fBqb_ipc_request_header\fP at the top of the message\&. The server will read the size field to determine how much to recv\&.
|
||||
.PP
|
||||
that msg_ptr will include a \fBqb_ipc_response_header\fP at the top of the message\&.
|
||||
.RE
|
||||
.PP
|
||||
\fBSee also:\fP
|
||||
.RS 4
|
||||
\fBqb_ipcc_sendv()\fP \fBqb_ipcc_recv()\fP
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbipcs.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbipcs.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -30,6 +30,9 @@ Server IPC API\&.
|
||||
.RI "struct \fBqb_ipcs_connection_stats\fP"
|
||||
.br
|
||||
.ti -1c
|
||||
.RI "struct \fBqb_ipcs_connection_stats_2\fP"
|
||||
.br
|
||||
.ti -1c
|
||||
.RI "struct \fBqb_ipcs_poll_handlers\fP"
|
||||
.br
|
||||
.ti -1c
|
||||
@ -164,6 +167,10 @@ Server IPC API\&.
|
||||
.br
|
||||
.RI "\fIGet the connection statistics\&. \fP"
|
||||
.ti -1c
|
||||
.RI "struct \fBqb_ipcs_connection_stats_2\fP * \fBqb_ipcs_connection_stats_get_2\fP (\fBqb_ipcs_connection_t\fP *c, int32_t clear_after_read)"
|
||||
.br
|
||||
.RI "\fIGet (and allocate) the connection statistics\&. \fP"
|
||||
.ti -1c
|
||||
.RI "int32_t \fBqb_ipcs_stats_get\fP (\fBqb_ipcs_service_t\fP *pt, struct \fBqb_ipcs_stats\fP *stats, int32_t clear_after_read)"
|
||||
.br
|
||||
.RI "\fIGet the service statistics\&. \fP"
|
||||
@ -175,6 +182,10 @@ Server IPC API\&.
|
||||
.RI "\fBqb_ipcs_connection_t\fP * \fBqb_ipcs_connection_next_get\fP (\fBqb_ipcs_service_t\fP *pt, \fBqb_ipcs_connection_t\fP *current)"
|
||||
.br
|
||||
.RI "\fIGet the next connection\&. \fP"
|
||||
.ti -1c
|
||||
.RI "void \fBqb_ipcs_connection_auth_set\fP (\fBqb_ipcs_connection_t\fP *conn, uid_t uid, gid_t gid, mode_t mode)"
|
||||
.br
|
||||
.RI "\fISet the permissions on and shared memory files so that both processes can read and write to them\&. \fP"
|
||||
.in -1c
|
||||
.SH "Detailed Description"
|
||||
.PP
|
||||
@ -183,18 +194,23 @@ Server IPC API\&.
|
||||
|
||||
.SH "Typedef Documentation"
|
||||
.PP
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_connection_accept_fn\fP)(\fBqb_ipcs_connection_t\fP *c, uid_t uid, gid_t gid)"
|
||||
.SS "typedef int32_t(* qb_ipcs_connection_accept_fn)(\fBqb_ipcs_connection_t\fP *c, uid_t uid, gid_t gid)"
|
||||
|
||||
.PP
|
||||
This callback is to check wether you want to accept a new connection\&. The type of checks you should do are authentication, service availabilty or process resource constraints\&.
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
0 to accept or -errno to indicate a failure (sent back to the client)
|
||||
0 to accept or -errno to indicate a failure (sent back to the client)
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
you can call \fBqb_ipcs_connection_auth_set()\fP within this function\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_connection_closed_fn\fP)(\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "typedef int32_t(* qb_ipcs_connection_closed_fn)(\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
This is called after a connection has been disconnected\&. \fBNote:\fP
|
||||
@ -203,27 +219,27 @@ if you return anything but 0 this function will be repeativily called (until 0 i
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "typedef void(* \fBqb_ipcs_connection_created_fn\fP)(\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "typedef void(* qb_ipcs_connection_created_fn)(\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
This is called after a new connection has been created\&.
|
||||
.SS "typedef void(* \fBqb_ipcs_connection_destroyed_fn\fP)(\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "typedef void(* qb_ipcs_connection_destroyed_fn)(\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
This is called just before a connection is freed\&.
|
||||
.SS "typedef struct qb_ipcs_connection \fBqb_ipcs_connection_t\fP"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_dispatch_add_fn\fP)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)"
|
||||
.SS "typedef int32_t(* qb_ipcs_dispatch_add_fn)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_dispatch_del_fn\fP)(int32_t fd)"
|
||||
.SS "typedef int32_t(* qb_ipcs_dispatch_del_fn)(int32_t fd)"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_dispatch_fn_t\fP)(int32_t fd, int32_t revents, void *data)"
|
||||
.SS "typedef int32_t(* qb_ipcs_dispatch_fn_t)(int32_t fd, int32_t revents, void *data)"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_dispatch_mod_fn\fP)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)"
|
||||
.SS "typedef int32_t(* qb_ipcs_dispatch_mod_fn)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_job_add_fn\fP)(enum \fBqb_loop_priority\fP p, void *data, \fBqb_loop_job_dispatch_fn\fP dispatch_fn)"
|
||||
.SS "typedef int32_t(* qb_ipcs_job_add_fn)(enum \fBqb_loop_priority\fP p, void *data, \fBqb_loop_job_dispatch_fn\fP dispatch_fn)"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_ipcs_msg_process_fn\fP)(\fBqb_ipcs_connection_t\fP *c, void *data, size_t size)"
|
||||
.SS "typedef int32_t(* qb_ipcs_msg_process_fn)(\fBqb_ipcs_connection_t\fP *c, void *data, size_t size)"
|
||||
|
||||
.PP
|
||||
This is the message processing calback\&. It is called with the message data\&.
|
||||
@ -249,7 +265,32 @@ This is the message processing calback\&. It is called with the message data\&.
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "\fBqb_ipcs_connection_t\fP* \fBqb_ipcs_connection_first_get\fP (\fBqb_ipcs_service_t\fP *pt)"
|
||||
.SS "void qb_ipcs_connection_auth_set (\fBqb_ipcs_connection_t\fP *conn, uid_tuid, gid_tgid, mode_tmode)"
|
||||
|
||||
.PP
|
||||
Set the permissions on and shared memory files so that both processes can read and write to them\&. \fBParameters:\fP
|
||||
.RS 4
|
||||
\fIconn\fP connection instance
|
||||
.br
|
||||
\fIuid\fP the user id to set\&.
|
||||
.br
|
||||
\fIgid\fP the group id to set\&.
|
||||
.br
|
||||
\fImode\fP the mode to set\&.
|
||||
.RE
|
||||
.PP
|
||||
\fBSee also:\fP
|
||||
.RS 4
|
||||
chmod() chown()
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
this must be called within the \fBqb_ipcs_connection_accept_fn()\fP callback\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "\fBqb_ipcs_connection_t\fP* qb_ipcs_connection_first_get (\fBqb_ipcs_service_t\fP *pt)"
|
||||
|
||||
.PP
|
||||
Get the first connection\&. \fBNote:\fP
|
||||
@ -268,7 +309,7 @@ first connection
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "\fBqb_ipcs_connection_t\fP* \fBqb_ipcs_connection_next_get\fP (\fBqb_ipcs_service_t\fP *pt, \fBqb_ipcs_connection_t\fP *current)"
|
||||
.SS "\fBqb_ipcs_connection_t\fP* qb_ipcs_connection_next_get (\fBqb_ipcs_service_t\fP *pt, \fBqb_ipcs_connection_t\fP *current)"
|
||||
|
||||
.PP
|
||||
Get the next connection\&. \fBNote:\fP
|
||||
@ -289,7 +330,7 @@ next connection
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_connection_ref\fP (\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "void qb_ipcs_connection_ref (\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Increment the connection's reference counter\&. \fBParameters:\fP
|
||||
@ -298,10 +339,15 @@ Increment the connection's reference counter\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_ipcs_connection_stats_get\fP (\fBqb_ipcs_connection_t\fP *c, struct \fBqb_ipcs_connection_stats\fP *stats, int32_tclear_after_read)"
|
||||
.SS "int32_t qb_ipcs_connection_stats_get (\fBqb_ipcs_connection_t\fP *c, struct \fBqb_ipcs_connection_stats\fP *stats, int32_tclear_after_read)"
|
||||
|
||||
.PP
|
||||
Get the connection statistics\&. \fBParameters:\fP
|
||||
Get the connection statistics\&. \fBDeprecated\fP
|
||||
.RS 4
|
||||
from v0\&.13\&.0 onwards, use qb_ipcs_connection_stats_get_2
|
||||
.RE
|
||||
.PP
|
||||
\fBParameters:\fP
|
||||
.RS 4
|
||||
\fIstats\fP (out) the statistics structure
|
||||
.br
|
||||
@ -316,7 +362,25 @@ Get the connection statistics\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_connection_unref\fP (\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "struct \fBqb_ipcs_connection_stats_2\fP* qb_ipcs_connection_stats_get_2 (\fBqb_ipcs_connection_t\fP *c, int32_tclear_after_read)\fC [read]\fP"
|
||||
|
||||
.PP
|
||||
Get (and allocate) the connection statistics\&. \fBParameters:\fP
|
||||
.RS 4
|
||||
\fIclear_after_read\fP clear stats after copying them into stats
|
||||
.br
|
||||
\fIc\fP connection instance
|
||||
.RE
|
||||
.PP
|
||||
\fBReturn values:\fP
|
||||
.RS 4
|
||||
\fINULL\fP if no memory or invalid connection
|
||||
.br
|
||||
\fIallocated\fP statistics structure (user must free it)\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void qb_ipcs_connection_unref (\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Decrement the connection's reference counter\&. \fBParameters:\fP
|
||||
@ -325,7 +389,7 @@ Decrement the connection's reference counter\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void* \fBqb_ipcs_context_get\fP (\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "void* qb_ipcs_context_get (\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Get the context (set previously) \fBParameters:\fP
|
||||
@ -344,7 +408,7 @@ the context
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_context_set\fP (\fBqb_ipcs_connection_t\fP *c, void *context)"
|
||||
.SS "void qb_ipcs_context_set (\fBqb_ipcs_connection_t\fP *c, void *context)"
|
||||
|
||||
.PP
|
||||
Associate a 'user' pointer with this connection\&. \fBParameters:\fP
|
||||
@ -360,7 +424,7 @@ Associate a 'user' pointer with this connection\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "\fBqb_ipcs_service_t\fP* \fBqb_ipcs_create\fP (const char *name, int32_tservice_id, enum \fBqb_ipc_type\fPtype, struct \fBqb_ipcs_service_handlers\fP *handlers)"
|
||||
.SS "\fBqb_ipcs_service_t\fP* qb_ipcs_create (const char *name, int32_tservice_id, enum \fBqb_ipc_type\fPtype, struct \fBqb_ipcs_service_handlers\fP *handlers)"
|
||||
|
||||
.PP
|
||||
Create a new IPC server\&. \fBParameters:\fP
|
||||
@ -380,7 +444,7 @@ the new service instance\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_destroy\fP (\fBqb_ipcs_service_t\fP *s)"
|
||||
.SS "void qb_ipcs_destroy (\fBqb_ipcs_service_t\fP *s)"
|
||||
|
||||
.PP
|
||||
Destroy the IPC server\&. \fBParameters:\fP
|
||||
@ -389,7 +453,7 @@ Destroy the IPC server\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_disconnect\fP (\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "void qb_ipcs_disconnect (\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Disconnect from this client\&. \fBParameters:\fP
|
||||
@ -398,7 +462,7 @@ Disconnect from this client\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcs_event_send\fP (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)"
|
||||
.SS "ssize_t qb_ipcs_event_send (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)"
|
||||
|
||||
.PP
|
||||
Send an asyncronous event message to the client\&. \fBParameters:\fP
|
||||
@ -412,11 +476,16 @@ Send an asyncronous event message to the client\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
size sent or -errno for errors
|
||||
size sent or -errno for errors
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
the data must include a \fBqb_ipc_response_header\fP at the top of the message\&. The client will read the size field to determine how much to recv\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcs_event_sendv\fP (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)"
|
||||
.SS "ssize_t qb_ipcs_event_sendv (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)"
|
||||
|
||||
.PP
|
||||
Send an asyncronous event message to the client\&. \fBParameters:\fP
|
||||
@ -430,11 +499,16 @@ Send an asyncronous event message to the client\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
size sent or -errno for errors
|
||||
size sent or -errno for errors
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
the iov[0] must be a \fBqb_ipc_response_header\fP\&. The client will read the size field to determine how much to recv\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_poll_handlers_set\fP (\fBqb_ipcs_service_t\fP *s, struct \fBqb_ipcs_poll_handlers\fP *handlers)"
|
||||
.SS "void qb_ipcs_poll_handlers_set (\fBqb_ipcs_service_t\fP *s, struct \fBqb_ipcs_poll_handlers\fP *handlers)"
|
||||
|
||||
.PP
|
||||
Set your poll callbacks\&. \fBParameters:\fP
|
||||
@ -445,7 +519,7 @@ Set your poll callbacks\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_ref\fP (\fBqb_ipcs_service_t\fP *s)"
|
||||
.SS "void qb_ipcs_ref (\fBqb_ipcs_service_t\fP *s)"
|
||||
|
||||
.PP
|
||||
Increase the reference counter on the service object\&. \fBParameters:\fP
|
||||
@ -454,7 +528,7 @@ Increase the reference counter on the service object\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_request_rate_limit\fP (\fBqb_ipcs_service_t\fP *s, enum \fBqb_ipcs_rate_limit\fPrl)"
|
||||
.SS "void qb_ipcs_request_rate_limit (\fBqb_ipcs_service_t\fP *s, enum \fBqb_ipcs_rate_limit\fPrl)"
|
||||
|
||||
.PP
|
||||
Limit the incomming request rate\&. \fBParameters:\fP
|
||||
@ -465,7 +539,7 @@ Limit the incomming request rate\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcs_response_send\fP (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)"
|
||||
.SS "ssize_t qb_ipcs_response_send (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)"
|
||||
|
||||
.PP
|
||||
Send a response to a incomming request\&. \fBParameters:\fP
|
||||
@ -479,11 +553,16 @@ Send a response to a incomming request\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
size sent or -errno for errors
|
||||
size sent or -errno for errors
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
the data must include a \fBqb_ipc_response_header\fP at the top of the message\&. The client will read the size field to determine how much to recv\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "ssize_t \fBqb_ipcs_response_sendv\fP (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)"
|
||||
.SS "ssize_t qb_ipcs_response_sendv (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)"
|
||||
|
||||
.PP
|
||||
Send a response to a incomming request\&. \fBParameters:\fP
|
||||
@ -497,11 +576,16 @@ Send a response to a incomming request\&. \fBParameters:\fP
|
||||
.PP
|
||||
\fBReturns:\fP
|
||||
.RS 4
|
||||
size sent or -errno for errors
|
||||
size sent or -errno for errors
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP
|
||||
.RS 4
|
||||
the iov[0] must be a \fBqb_ipc_response_header\fP\&. The client will read the size field to determine how much to recv\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_ipcs_run\fP (\fBqb_ipcs_service_t\fP *s)"
|
||||
.SS "int32_t qb_ipcs_run (\fBqb_ipcs_service_t\fP *s)"
|
||||
|
||||
.PP
|
||||
run the new IPC server\&. \fBParameters:\fP
|
||||
@ -515,7 +599,7 @@ run the new IPC server\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_ipcs_service_id_get\fP (\fBqb_ipcs_connection_t\fP *c)"
|
||||
.SS "int32_t qb_ipcs_service_id_get (\fBqb_ipcs_connection_t\fP *c)"
|
||||
|
||||
.PP
|
||||
Get the service id related to this connection's service\&. (as passed into \fBqb_ipcs_create()\fP
|
||||
@ -526,7 +610,7 @@ service id\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_ipcs_stats_get\fP (\fBqb_ipcs_service_t\fP *pt, struct \fBqb_ipcs_stats\fP *stats, int32_tclear_after_read)"
|
||||
.SS "int32_t qb_ipcs_stats_get (\fBqb_ipcs_service_t\fP *pt, struct \fBqb_ipcs_stats\fP *stats, int32_tclear_after_read)"
|
||||
|
||||
.PP
|
||||
Get the service statistics\&. \fBParameters:\fP
|
||||
@ -544,7 +628,7 @@ Get the service statistics\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_ipcs_unref\fP (\fBqb_ipcs_service_t\fP *s)"
|
||||
.SS "void qb_ipcs_unref (\fBqb_ipcs_service_t\fP *s)"
|
||||
|
||||
.PP
|
||||
Decrease the reference counter on the service object\&. \fBParameters:\fP
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qblist.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qblist.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -21,7 +21,7 @@ This is a kernel style list implementation\&.
|
||||
.RI "struct \fBqb_list_head\fP"
|
||||
.br
|
||||
.in -1c
|
||||
.SS "Defines"
|
||||
.SS "Macros"
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
@ -106,9 +106,9 @@ Steven Dake sdake@redhat.com
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SH "Define Documentation"
|
||||
.SH "Macro Definition Documentation"
|
||||
.PP
|
||||
.SS "#define \fBQB_INIT_LIST_HEAD\fP(ptr)"
|
||||
.SS "#define QB_INIT_LIST_HEAD(ptr)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -116,11 +116,11 @@ do { \
|
||||
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
|
||||
} while (0)
|
||||
.fi
|
||||
.SS "#define \fBQB_LIST_DECLARE\fP(name) struct \fBqb_list_head\fP name = { &(name), &(name) }"
|
||||
.SS "#define QB_LIST_DECLARE(name) struct \fBqb_list_head\fP name = { &(name), &(name) }"
|
||||
|
||||
.PP
|
||||
Declare and initialize a list head\&.
|
||||
.SS "#define \fBqb_list_entry\fP(ptr, type, member) ((type *)((char *)(ptr)-(char*)(&((type *)0)->member)))"
|
||||
.SS "#define qb_list_entry(ptr, type, member) ((type *)((char *)(ptr)-(char*)(&((type *)0)->member)))"
|
||||
|
||||
.PP
|
||||
Get the struct for this entry\&. \fBParameters:\fP
|
||||
@ -133,7 +133,7 @@ Get the struct for this entry\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_list_for_each\fP(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)"
|
||||
.SS "#define qb_list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)"
|
||||
|
||||
.PP
|
||||
Iterate over a list\&. \fBParameters:\fP
|
||||
@ -146,7 +146,7 @@ Iterate over a list\&. \fBParameters:\fP
|
||||
|
||||
.PP
|
||||
Referenced by qb_list_length()\&.
|
||||
.SS "#define \fBqb_list_for_each_entry\fP(pos, head, member)"
|
||||
.SS "#define qb_list_for_each_entry(pos, head, member)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -165,7 +165,7 @@ Iterate over list of given type\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_list_for_each_entry_reverse\fP(pos, head, member)"
|
||||
.SS "#define qb_list_for_each_entry_reverse(pos, head, member)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -184,7 +184,7 @@ Iterate backwards over list of given type\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_list_for_each_entry_safe\fP(pos, n, head, member)"
|
||||
.SS "#define qb_list_for_each_entry_safe(pos, n, head, member)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -206,7 +206,7 @@ Iterate over list of given type safe against removal of list entry\&. \fBParamet
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_list_for_each_entry_safe_reverse\fP(pos, n, head, member)"
|
||||
.SS "#define qb_list_for_each_entry_safe_reverse(pos, n, head, member)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -228,7 +228,7 @@ Iterate backwards over list safe against removal\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_list_for_each_reverse\fP(pos, head) for (pos = (head)->prev; pos != (head); pos = pos->prev)"
|
||||
.SS "#define qb_list_for_each_reverse(pos, head) for (pos = (head)->prev; pos != (head); pos = pos->prev)"
|
||||
|
||||
.PP
|
||||
Iterate over a list backwards\&. \fBParameters:\fP
|
||||
@ -239,7 +239,7 @@ Iterate over a list backwards\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_list_for_each_safe\fP(pos, n, head)"
|
||||
.SS "#define qb_list_for_each_safe(pos, n, head)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -259,7 +259,7 @@ Iterate over a list safe against removal of list entry\&. \fBParameters:\fP
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "static void \fBqb_list_add\fP (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline, static]\fP"
|
||||
.SS "static void qb_list_add (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP"
|
||||
|
||||
.PP
|
||||
Add this element to the list\&. \fBParameters:\fP
|
||||
@ -272,7 +272,7 @@ Add this element to the list\&. \fBParameters:\fP
|
||||
|
||||
.PP
|
||||
References qb_list_head::next, and qb_list_head::prev\&.
|
||||
.SS "static void \fBqb_list_add_tail\fP (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline, static]\fP"
|
||||
.SS "static void qb_list_add_tail (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP"
|
||||
|
||||
.PP
|
||||
Add to the list (but at the end of the list)\&. \fBParameters:\fP
|
||||
@ -290,7 +290,7 @@ Add to the list (but at the end of the list)\&. \fBParameters:\fP
|
||||
|
||||
.PP
|
||||
References qb_list_head::next, and qb_list_head::prev\&.
|
||||
.SS "static void \fBqb_list_del\fP (struct \fBqb_list_head\fP *_remove)\fC [inline, static]\fP"
|
||||
.SS "static void qb_list_del (struct \fBqb_list_head\fP *_remove)\fC [inline]\fP, \fC [static]\fP"
|
||||
|
||||
.PP
|
||||
Delete an entry from the list\&. \fBParameters:\fP
|
||||
@ -301,7 +301,7 @@ Delete an entry from the list\&. \fBParameters:\fP
|
||||
|
||||
.PP
|
||||
References qb_list_head::next, and qb_list_head::prev\&.
|
||||
.SS "static int32_t \fBqb_list_empty\fP (const struct \fBqb_list_head\fP *head)\fC [inline, static]\fP"
|
||||
.SS "static int32_t qb_list_empty (const struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP"
|
||||
|
||||
.PP
|
||||
A quick test to see if the list is empty (pointing to it's self)\&. \fBParameters:\fP
|
||||
@ -317,7 +317,7 @@ boolean true/false
|
||||
|
||||
.PP
|
||||
References qb_list_head::next\&.
|
||||
.SS "static void \fBqb_list_init\fP (struct \fBqb_list_head\fP *head)\fC [inline, static]\fP"
|
||||
.SS "static void qb_list_init (struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP"
|
||||
|
||||
.PP
|
||||
Initialize the list entry\&. Points next and prev pointers to head\&.
|
||||
@ -330,7 +330,7 @@ Initialize the list entry\&. Points next and prev pointers to head\&.
|
||||
|
||||
.PP
|
||||
References qb_list_head::next, and qb_list_head::prev\&.
|
||||
.SS "static int32_t \fBqb_list_length\fP (struct \fBqb_list_head\fP *head)\fC [inline, static]\fP"
|
||||
.SS "static int32_t qb_list_length (struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP"
|
||||
|
||||
.PP
|
||||
Count the number of items in the list\&. \fBParameters:\fP
|
||||
@ -346,7 +346,7 @@ length of the list\&.
|
||||
|
||||
.PP
|
||||
References qb_list_for_each\&.
|
||||
.SS "static void \fBqb_list_splice\fP (struct \fBqb_list_head\fP *list, struct \fBqb_list_head\fP *head)\fC [inline, static]\fP"
|
||||
.SS "static void qb_list_splice (struct \fBqb_list_head\fP *list, struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP"
|
||||
|
||||
.PP
|
||||
Join two lists\&. \fBParameters:\fP
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qblog.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qblog.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -36,7 +36,7 @@ The logging API provides four main parts (basics, filtering, threading & blackbo
|
||||
.br
|
||||
.RI "\fIAn instance of this structure is created in a special ELF section at every dynamic debug callsite\&. \fP"
|
||||
.in -1c
|
||||
.SS "Defines"
|
||||
.SS "Macros"
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
@ -120,7 +120,7 @@ The logging API provides four main parts (basics, filtering, threading & blackbo
|
||||
.RI "enum \fBqb_log_target_state\fP { \fBQB_LOG_STATE_UNUSED\fP = 1, \fBQB_LOG_STATE_DISABLED\fP = 2, \fBQB_LOG_STATE_ENABLED\fP = 3 }"
|
||||
.br
|
||||
.ti -1c
|
||||
.RI "enum \fBqb_log_conf\fP { \fBQB_LOG_CONF_ENABLED\fP, \fBQB_LOG_CONF_FACILITY\fP, \fBQB_LOG_CONF_DEBUG\fP, \fBQB_LOG_CONF_SIZE\fP, \fBQB_LOG_CONF_THREADED\fP, \fBQB_LOG_CONF_PRIORITY_BUMP\fP, \fBQB_LOG_CONF_STATE_GET\fP }"
|
||||
.RI "enum \fBqb_log_conf\fP { \fBQB_LOG_CONF_ENABLED\fP, \fBQB_LOG_CONF_FACILITY\fP, \fBQB_LOG_CONF_DEBUG\fP, \fBQB_LOG_CONF_SIZE\fP, \fBQB_LOG_CONF_THREADED\fP, \fBQB_LOG_CONF_PRIORITY_BUMP\fP, \fBQB_LOG_CONF_STATE_GET\fP, \fBQB_LOG_CONF_FILE_SYNC\fP }"
|
||||
.br
|
||||
.ti -1c
|
||||
.RI "enum \fBqb_log_filter_type\fP { \fBQB_LOG_FILTER_FILE\fP, \fBQB_LOG_FILTER_FUNCTION\fP, \fBQB_LOG_FILTER_FORMAT\fP }"
|
||||
@ -294,13 +294,13 @@ Call \fBqb_log()\fP to generate a log message\&. Then to write the message somew
|
||||
Simplist possible use:
|
||||
.PP
|
||||
.nf
|
||||
main() {
|
||||
main() {
|
||||
qb_log_init('simple-log', LOG_DAEMON, LOG_INFO);
|
||||
// \&.\&.\&.
|
||||
qb_log(LOG_WARNING, 'watch out');
|
||||
// \&.\&.\&.
|
||||
qb_log_fini();
|
||||
}
|
||||
}
|
||||
|
||||
.fi
|
||||
.PP
|
||||
@ -349,6 +349,14 @@ To workaround your syslog daemon filtering all messages > LOG_INFO
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP,
|
||||
LOG_INFO - LOG_DEBUG);
|
||||
|
||||
.fi
|
||||
.PP
|
||||
.PP
|
||||
To ensure all logs to file targets are fsync'ed (default QB_FALSE)
|
||||
.PP
|
||||
.nf
|
||||
qb_log_ctl(mytarget, QB_LOG_CONF_FILE_SYNC, QB_TRUE);
|
||||
|
||||
.fi
|
||||
.PP
|
||||
.PP
|
||||
@ -399,7 +407,7 @@ To achieve non-blocking logging you can use threaded logging\&. So any calls to
|
||||
Threaded logging use:
|
||||
.PP
|
||||
.nf
|
||||
main() {
|
||||
main() {
|
||||
qb_log_init('simple-log', LOG_DAEMON, LOG_INFO);
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE);
|
||||
// \&.\&.\&.
|
||||
@ -410,7 +418,7 @@ Threaded logging use:
|
||||
qb_log(LOG_WARNING, 'watch out');
|
||||
// \&.\&.\&.
|
||||
qb_log_fini();
|
||||
}
|
||||
}
|
||||
|
||||
.fi
|
||||
.PP
|
||||
@ -428,18 +436,18 @@ the blackbox is not enabled by default\&.
|
||||
Blackbox usage:
|
||||
.PP
|
||||
.nf
|
||||
static void sigsegv_handler(int sig)
|
||||
{
|
||||
static void sigsegv_handler(int sig)
|
||||
{
|
||||
(void)signal (SIGSEGV, SIG_DFL);
|
||||
qb_log_blackbox_write_to_file('simple-log\&.fdata');
|
||||
qb_log_fini();
|
||||
raise(SIGSEGV);
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
signal(SIGSEGV, sigsegv_handler);
|
||||
|
||||
|
||||
qb_log_init('simple-log', LOG_DAEMON, LOG_INFO);
|
||||
qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, '*', LOG_DEBUG);
|
||||
@ -449,7 +457,7 @@ Blackbox usage:
|
||||
qb_log(LOG_WARNING, 'watch out');
|
||||
// \&.\&.\&.
|
||||
qb_log_fini();
|
||||
}
|
||||
}
|
||||
|
||||
.fi
|
||||
.PP
|
||||
@ -461,7 +469,7 @@ You can tag messages using the second argument to \fBqb_logt()\fP or by using \f
|
||||
.PP
|
||||
.PP
|
||||
.nf
|
||||
const char* my_tags_stringify(uint32_t tags) {
|
||||
const char* my_tags_stringify(uint32_t tags) {
|
||||
if (qb_bit_is_set(tags, QB_LOG_TAG_LIBQB_MSG_BIT) {
|
||||
return 'libqb';
|
||||
} else if (tags == 3) {
|
||||
@ -469,36 +477,36 @@ You can tag messages using the second argument to \fBqb_logt()\fP or by using \f
|
||||
} else {
|
||||
return 'MAIN';
|
||||
}
|
||||
}
|
||||
main() {
|
||||
}
|
||||
main() {
|
||||
// \&.\&.\&.
|
||||
qb_log_tags_stringify_fn_set(my_tags_stringify);
|
||||
qb_log_format_set(QB_LOG_STDERR, '[%5g] %p %b');
|
||||
// \&.\&.\&.
|
||||
qb_logt(LOG_INFO, 3, 'hello');
|
||||
qb_logt(LOG_INFO, 0, 'hello');
|
||||
}
|
||||
}
|
||||
.fi
|
||||
.PP
|
||||
The code above will produce:
|
||||
.PP
|
||||
.nf
|
||||
[libqb] some message
|
||||
[three] info hello
|
||||
[MAIN ] info hello
|
||||
[libqb] some message
|
||||
[three] info hello
|
||||
[MAIN ] info hello
|
||||
|
||||
.fi
|
||||
.PP
|
||||
|
||||
.SH "Define Documentation"
|
||||
.SH "Macro Definition Documentation"
|
||||
.PP
|
||||
.SS "#define \fBLOG_TRACE\fP (LOG_DEBUG + 1)"
|
||||
.SS "#define LOG_TRACE (LOG_DEBUG + 1)"
|
||||
|
||||
.SS "#define \fBqb_enter\fP() \fBqb_log\fP(\fBLOG_TRACE\fP, 'ENTERING %s()', __func__)"
|
||||
.SS "#define qb_enter() \fBqb_log\fP(\fBLOG_TRACE\fP, 'ENTERING %s()', __func__)"
|
||||
|
||||
.SS "#define \fBqb_leave\fP() \fBqb_log\fP(\fBLOG_TRACE\fP, 'LEAVING %s()', __func__)"
|
||||
.SS "#define qb_leave() \fBqb_log\fP(\fBLOG_TRACE\fP, 'LEAVING %s()', __func__)"
|
||||
|
||||
.SS "#define \fBqb_log\fP(\fBpriority\fP, fmt, args\&.\&.\&.) \fBqb_logt\fP(\fBpriority\fP, 0, fmt, ##args)"
|
||||
.SS "#define qb_log(\fBpriority\fP, fmt, args\&.\&.\&.) \fBqb_logt\fP(\fBpriority\fP, 0, fmt, ##args)"
|
||||
|
||||
.PP
|
||||
This is the main function to generate a log message\&. \fBParameters:\fP
|
||||
@ -511,9 +519,9 @@ This is the main function to generate a log message\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBQB_LOG_BLACKBOX\fP 2"
|
||||
.SS "#define QB_LOG_BLACKBOX 2"
|
||||
|
||||
.SS "#define \fBQB_LOG_INIT_DATA\fP(name)"
|
||||
.SS "#define QB_LOG_INIT_DATA(name)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -521,23 +529,23 @@ void name(void); \
|
||||
void name(void) { if (__start___verbose != __stop___verbose) {assert(1);} } \
|
||||
void __attribute__ ((constructor)) name(void);
|
||||
.fi
|
||||
.SS "#define \fBQB_LOG_MAX_LEN\fP 512"
|
||||
.SS "#define QB_LOG_MAX_LEN 512"
|
||||
|
||||
.SS "#define \fBQB_LOG_STDERR\fP 1"
|
||||
.SS "#define QB_LOG_STDERR 1"
|
||||
|
||||
.SS "#define \fBQB_LOG_STDOUT\fP 3"
|
||||
.SS "#define QB_LOG_STDOUT 3"
|
||||
|
||||
.SS "#define \fBQB_LOG_STRERROR_MAX_LEN\fP 128"
|
||||
.SS "#define QB_LOG_STRERROR_MAX_LEN 128"
|
||||
|
||||
.SS "#define \fBQB_LOG_SYSLOG\fP 0"
|
||||
.SS "#define QB_LOG_SYSLOG 0"
|
||||
|
||||
.SS "#define \fBQB_LOG_TAG_LIBQB_MSG\fP (1 << \fBQB_LOG_TAG_LIBQB_MSG_BIT\fP)"
|
||||
.SS "#define QB_LOG_TAG_LIBQB_MSG (1 << \fBQB_LOG_TAG_LIBQB_MSG_BIT\fP)"
|
||||
|
||||
.SS "#define \fBQB_LOG_TAG_LIBQB_MSG_BIT\fP 31"
|
||||
.SS "#define QB_LOG_TAG_LIBQB_MSG_BIT 31"
|
||||
|
||||
.SS "#define \fBQB_LOG_TARGET_MAX\fP 32"
|
||||
.SS "#define QB_LOG_TARGET_MAX 32"
|
||||
|
||||
.SS "#define \fBqb_logt\fP(\fBpriority\fP, \fBtags\fP, fmt, args\&.\&.\&.)"
|
||||
.SS "#define qb_logt(\fBpriority\fP, \fBtags\fP, fmt, args\&.\&.\&.)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -561,7 +569,7 @@ This is the function to generate a log message if you want to manually add tags\
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "#define \fBqb_perror\fP(\fBpriority\fP, fmt, args\&.\&.\&.)"
|
||||
.SS "#define qb_perror(\fBpriority\fP, fmt, args\&.\&.\&.)"
|
||||
\fBValue:\fP
|
||||
.PP
|
||||
.nf
|
||||
@ -584,17 +592,17 @@ This is similar to perror except it goes into the logging system\&. \fBParameter
|
||||
|
||||
.SH "Typedef Documentation"
|
||||
.PP
|
||||
.SS "typedef void(* \fBqb_log_close_fn\fP)(int32_t t)"
|
||||
.SS "typedef void(* qb_log_close_fn)(int32_t t)"
|
||||
|
||||
.SS "typedef void(* \fBqb_log_filter_fn\fP)(struct \fBqb_log_callsite\fP *cs)"
|
||||
.SS "typedef void(* qb_log_filter_fn)(struct \fBqb_log_callsite\fP *cs)"
|
||||
|
||||
.SS "typedef void(* \fBqb_log_logger_fn\fP)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, const char *msg)"
|
||||
.SS "typedef void(* qb_log_logger_fn)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, const char *msg)"
|
||||
|
||||
.SS "typedef void(* \fBqb_log_reload_fn\fP)(int32_t t)"
|
||||
.SS "typedef void(* qb_log_reload_fn)(int32_t t)"
|
||||
|
||||
.SS "typedef const char*(* \fBqb_log_tags_stringify_fn\fP)(uint32_t \fBtags\fP)"
|
||||
.SS "typedef const char*(* qb_log_tags_stringify_fn)(uint32_t \fBtags\fP)"
|
||||
|
||||
.SS "typedef void(* \fBqb_log_vlogger_fn\fP)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, va_list ap)"
|
||||
.SS "typedef void(* qb_log_vlogger_fn)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, va_list ap)"
|
||||
|
||||
.SH "Enumeration Type Documentation"
|
||||
.PP
|
||||
@ -617,6 +625,8 @@ This is similar to perror except it goes into the logging system\&. \fBParameter
|
||||
\fB\fIQB_LOG_CONF_PRIORITY_BUMP \fP\fP
|
||||
.TP
|
||||
\fB\fIQB_LOG_CONF_STATE_GET \fP\fP
|
||||
.TP
|
||||
\fB\fIQB_LOG_CONF_FILE_SYNC \fP\fP
|
||||
|
||||
.SS "enum \fBqb_log_filter_conf\fP"
|
||||
|
||||
@ -662,17 +672,17 @@ This is similar to perror except it goes into the logging system\&. \fBParameter
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "struct \fBqb_log_callsite\fP \fB__attribute__\fP ((aligned(8)))"
|
||||
.SS "struct \fBqb_log_callsite\fP __attribute__ ((aligned(8)))"
|
||||
|
||||
.SS "void \fBqb_log_blackbox_print_from_file\fP (const char *filename)"
|
||||
.SS "void qb_log_blackbox_print_from_file (const char *filename)"
|
||||
|
||||
.PP
|
||||
Read the blackbox for file and print it out\&.
|
||||
.SS "ssize_t \fBqb_log_blackbox_write_to_file\fP (const char *filename)"
|
||||
.SS "ssize_t qb_log_blackbox_write_to_file (const char *filename)"
|
||||
|
||||
.PP
|
||||
Write the blackbox to file\&.
|
||||
.SS "struct \fBqb_log_callsite\fP* \fBqb_log_callsite_get\fP (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags)\fC [read]\fP"
|
||||
.SS "struct \fBqb_log_callsite\fP* qb_log_callsite_get (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags)\fC [read]\fP"
|
||||
|
||||
.PP
|
||||
Get or create a callsite at the give position\&. The result can then be passed into \fBqb_log_real_()\fP
|
||||
@ -693,11 +703,11 @@ Get or create a callsite at the give position\&. The result can then be passed i
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_log_callsites_dump\fP (void)"
|
||||
.SS "void qb_log_callsites_dump (void)"
|
||||
|
||||
.PP
|
||||
Dump the callsite info to stdout\&.
|
||||
.SS "int32_t \fBqb_log_callsites_register\fP (struct \fBqb_log_callsite\fP *_start, struct \fBqb_log_callsite\fP *_stop)"
|
||||
.SS "int32_t qb_log_callsites_register (struct \fBqb_log_callsite\fP *_start, struct \fBqb_log_callsite\fP *_stop)"
|
||||
|
||||
.PP
|
||||
If you are using dynamically loadable modules via dlopen() and you load them after \fBqb_log_init()\fP then after you load the module you will need to do the following to get the filters to work in that module\&. .PP
|
||||
@ -708,7 +718,7 @@ If you are using dynamically loadable modules via dlopen() and you load them aft
|
||||
.fi
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_log_ctl\fP (int32_ttarget, enum \fBqb_log_conf\fPconf_type, int32_targ)"
|
||||
.SS "int32_t qb_log_ctl (int32_ttarget, enum \fBqb_log_conf\fPconf_type, int32_targ)"
|
||||
|
||||
.PP
|
||||
Main logging control function\&. \fBParameters:\fP
|
||||
@ -735,11 +745,11 @@ Main logging control function\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_log_custom_close\fP (int32_tt)"
|
||||
.SS "void qb_log_custom_close (int32_tt)"
|
||||
|
||||
.PP
|
||||
Close a custom log target and release is resources\&.
|
||||
.SS "int32_t \fBqb_log_custom_open\fP (\fBqb_log_logger_fn\fPlog_fn, \fBqb_log_close_fn\fPclose_fn, \fBqb_log_reload_fn\fPreload_fn, void *user_data)"
|
||||
.SS "int32_t qb_log_custom_open (\fBqb_log_logger_fn\fPlog_fn, \fBqb_log_close_fn\fPclose_fn, \fBqb_log_reload_fn\fPreload_fn, void *user_data)"
|
||||
|
||||
.PP
|
||||
Open a custom log target\&. \fBReturn values:\fP
|
||||
@ -750,19 +760,19 @@ Open a custom log target\&. \fBReturn values:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_log_facility2int\fP (const char *fname)"
|
||||
.SS "int32_t qb_log_facility2int (const char *fname)"
|
||||
|
||||
.PP
|
||||
Convert string 'auth' to equivalent number 'LOG_AUTH' etc\&.
|
||||
.SS "const char* \fBqb_log_facility2str\fP (int32_tfnum)"
|
||||
.SS "const char* qb_log_facility2str (int32_tfnum)"
|
||||
|
||||
.PP
|
||||
Convert number 'LOG_AUTH' to equivalent string 'auth' etc\&.
|
||||
.SS "void \fBqb_log_file_close\fP (int32_tt)"
|
||||
.SS "void qb_log_file_close (int32_tt)"
|
||||
|
||||
.PP
|
||||
Close a log file and release is resources\&.
|
||||
.SS "int32_t \fBqb_log_file_open\fP (const char *filename)"
|
||||
.SS "int32_t qb_log_file_open (const char *filename)"
|
||||
|
||||
.PP
|
||||
Open a log file\&. \fBReturn values:\fP
|
||||
@ -773,22 +783,22 @@ Open a log file\&. \fBReturn values:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_log_filter_ctl\fP (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_tlow_priority)"
|
||||
.SS "int32_t qb_log_filter_ctl (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_tlow_priority)"
|
||||
|
||||
.PP
|
||||
This allows you modify the 'tags' and 'targets' callsite fields at runtime\&.
|
||||
.SS "int32_t \fBqb_log_filter_ctl2\fP (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_thigh_priority, uint8_tlow_priority)"
|
||||
.SS "int32_t qb_log_filter_ctl2 (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_thigh_priority, uint8_tlow_priority)"
|
||||
|
||||
.PP
|
||||
This extends \fBqb_log_filter_ctl()\fP by been able to provide a high_priority\&.
|
||||
.SS "int32_t \fBqb_log_filter_fn_set\fP (\fBqb_log_filter_fn\fPfn)"
|
||||
.SS "int32_t qb_log_filter_fn_set (\fBqb_log_filter_fn\fPfn)"
|
||||
|
||||
.PP
|
||||
Instead of using the \fBqb_log_filter_ctl()\fP functions you can apply the filters manually by defining a callback and setting the targets field using \fBqb_bit_set()\fP and \fBqb_bit_clear()\fP like the following below\&. .PP
|
||||
.nf
|
||||
static void
|
||||
m_filter(struct qb_log_callsite *cs)
|
||||
{
|
||||
static void
|
||||
m_filter(struct qb_log_callsite *cs)
|
||||
{
|
||||
if ((cs->priority >= LOG_ALERT &&
|
||||
cs->priority <= LOG_DEBUG) &&
|
||||
strcmp(cs->filename, 'my_c_file\&.c') == 0) {
|
||||
@ -796,21 +806,21 @@ Instead of using the \fBqb_log_filter_ctl()\fP functions you can apply the filte
|
||||
} else {
|
||||
qb_bit_clear(cs->targets, QB_LOG_SYSLOG);
|
||||
}
|
||||
}
|
||||
}
|
||||
.fi
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_log_fini\fP (void)"
|
||||
.SS "void qb_log_fini (void)"
|
||||
|
||||
.PP
|
||||
Logging system finalization function\&. It releases any shared memory\&. Stops the logging thread if running\&. Flushes the last message to their destinations\&.
|
||||
.SS "void \fBqb_log_format_set\fP (int32_tt, const char *format)"
|
||||
.SS "void qb_log_format_set (int32_tt, const char *format)"
|
||||
|
||||
.PP
|
||||
Set the format specifiers\&. n FUNCTION NAME f FILENAME l FILELINE p PRIORITY t TIMESTAMP b BUFFER g TAGS N name (passed into qb_log_init) P PID H hostname
|
||||
.PP
|
||||
any number between % and character specify field length to pad or chop
|
||||
.SS "void \fBqb_log_from_external_source\fP (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, \&.\&.\&.)"
|
||||
.SS "void qb_log_from_external_source (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, \&.\&.\&.)"
|
||||
|
||||
.PP
|
||||
This function is to import logs from other code (like libraries) that provide a callback with their logs\&. \fBNote:\fP
|
||||
@ -834,9 +844,9 @@ the performance of this will not impress you, as the filtering is done on each l
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_log_from_external_source_va\fP (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, va_listap)"
|
||||
.SS "void qb_log_from_external_source_va (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, va_listap)"
|
||||
|
||||
.SS "void \fBqb_log_init\fP (const char *name, int32_tfacility, uint8_tpriority)"
|
||||
.SS "void qb_log_init (const char *name, int32_tfacility, uint8_tpriority)"
|
||||
|
||||
.PP
|
||||
Init the logging system\&. \fBParameters:\fP
|
||||
@ -849,25 +859,25 @@ Init the logging system\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_log_real_\fP (struct \fBqb_log_callsite\fP *cs, \&.\&.\&.)"
|
||||
.SS "void qb_log_real_ (struct \fBqb_log_callsite\fP *cs, \&.\&.\&.)"
|
||||
|
||||
.PP
|
||||
Internal function: use \fBqb_log()\fP or \fBqb_logt()\fP
|
||||
.SS "void \fBqb_log_real_va_\fP (struct \fBqb_log_callsite\fP *cs, va_listap)"
|
||||
.SS "void qb_log_real_va_ (struct \fBqb_log_callsite\fP *cs, va_listap)"
|
||||
|
||||
.SS "void \fBqb_log_tags_stringify_fn_set\fP (\fBqb_log_tags_stringify_fn\fPfn)"
|
||||
.SS "void qb_log_tags_stringify_fn_set (\fBqb_log_tags_stringify_fn\fPfn)"
|
||||
|
||||
.PP
|
||||
Set the callback to map the 'tags' bit map to a string\&.
|
||||
.SS "void \fBqb_log_target_format\fP (int32_ttarget, struct \fBqb_log_callsite\fP *cs, time_ttimestamp, const char *formatted_message, char *output_buffer)"
|
||||
.SS "void qb_log_target_format (int32_ttarget, struct \fBqb_log_callsite\fP *cs, time_ttimestamp, const char *formatted_message, char *output_buffer)"
|
||||
|
||||
.PP
|
||||
format the callsite and timestamp info according to the format set using \fBqb_log_format_set()\fP It is intended to be used from your custom logger function\&.
|
||||
.SS "void* \fBqb_log_target_user_data_get\fP (int32_tt)"
|
||||
.SS "void* qb_log_target_user_data_get (int32_tt)"
|
||||
|
||||
.PP
|
||||
Retrieve the user data set by either qb_log_custom_open or qb_log_target_user_data_set\&.
|
||||
.SS "int32_t \fBqb_log_target_user_data_set\fP (int32_tt, void *user_data)"
|
||||
.SS "int32_t qb_log_target_user_data_set (int32_tt, void *user_data)"
|
||||
|
||||
.PP
|
||||
Associate user data with this log target\&. \fBNote:\fP
|
||||
@ -876,7 +886,7 @@ only use this with custom targets
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_log_thread_priority_set\fP (int32_tpolicy, int32_tpriority)"
|
||||
.SS "int32_t qb_log_thread_priority_set (int32_tpolicy, int32_tpriority)"
|
||||
|
||||
.PP
|
||||
When using threaded logging set the pthread policy and priority\&. \fBReturn values:\fP
|
||||
@ -887,31 +897,31 @@ When using threaded logging set the pthread policy and priority\&. \fBReturn val
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_log_thread_start\fP (void)"
|
||||
.SS "int32_t qb_log_thread_start (void)"
|
||||
|
||||
.PP
|
||||
Start the logging pthread\&.
|
||||
.SH "Variable Documentation"
|
||||
.PP
|
||||
.SS "enum \fBqb_log_target_state\fP \fB__attribute__\fP"
|
||||
.SS "enum \fBqb_log_target_state\fP __attribute__"
|
||||
|
||||
.SS "struct \fBqb_log_callsite\fP \fB__start___verbose\fP[]"
|
||||
.SS "struct \fBqb_log_callsite\fP __start___verbose[]"
|
||||
|
||||
.SS "struct \fBqb_log_callsite\fP \fB__stop___verbose\fP[]"
|
||||
.SS "struct \fBqb_log_callsite\fP __stop___verbose[]"
|
||||
|
||||
.SS "const char* \fBfilename\fP"
|
||||
.SS "const char* filename"
|
||||
|
||||
.SS "const char* \fBformat\fP"
|
||||
.SS "const char* format"
|
||||
|
||||
.SS "const char* \fBfunction\fP"
|
||||
.SS "const char* function"
|
||||
|
||||
.SS "uint32_t \fBlineno\fP"
|
||||
.SS "uint32_t lineno"
|
||||
|
||||
.SS "uint8_t \fBpriority\fP"
|
||||
.SS "uint8_t priority"
|
||||
|
||||
.SS "uint32_t \fBtags\fP"
|
||||
.SS "uint32_t tags"
|
||||
|
||||
.SS "uint32_t \fBtargets\fP"
|
||||
.SS "uint32_t targets"
|
||||
|
||||
.SH "Author"
|
||||
.PP
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbloop.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbloop.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -110,11 +110,11 @@ Main loop manages timers, jobs and polling sockets\&.
|
||||
.br
|
||||
.RI "\fIDelete a poll job\&. \fP"
|
||||
.ti -1c
|
||||
.RI "int32_t \fBqb_loop_signal_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t signal, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP *handle)"
|
||||
.RI "int32_t \fBqb_loop_signal_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t sig, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP *handle)"
|
||||
.br
|
||||
.RI "\fIAdd a signal job\&. \fP"
|
||||
.ti -1c
|
||||
.RI "int32_t \fBqb_loop_signal_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t signal, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP handle)"
|
||||
.RI "int32_t \fBqb_loop_signal_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t sig, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP handle)"
|
||||
.br
|
||||
.RI "\fIModify the signal job\&. \fP"
|
||||
.ti -1c
|
||||
@ -129,13 +129,13 @@ Main loop manages timers, jobs and polling sockets\&.
|
||||
|
||||
.SH "Typedef Documentation"
|
||||
.PP
|
||||
.SS "typedef void(* \fBqb_loop_job_dispatch_fn\fP)(void *data)"
|
||||
.SS "typedef void(* qb_loop_job_dispatch_fn)(void *data)"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_loop_poll_dispatch_fn\fP)(int32_t fd, int32_t revents, void *data)"
|
||||
.SS "typedef int32_t(* qb_loop_poll_dispatch_fn)(int32_t fd, int32_t revents, void *data)"
|
||||
|
||||
.SS "typedef void(* \fBqb_loop_poll_low_fds_event_fn\fP)(int32_t not_enough, int32_t fds_available)"
|
||||
.SS "typedef void(* qb_loop_poll_low_fds_event_fn)(int32_t not_enough, int32_t fds_available)"
|
||||
|
||||
.SS "typedef int32_t(* \fBqb_loop_signal_dispatch_fn\fP)(int32_t rsignal, void *data)"
|
||||
.SS "typedef int32_t(* qb_loop_signal_dispatch_fn)(int32_t rsignal, void *data)"
|
||||
|
||||
.SS "typedef void* \fBqb_loop_signal_handle\fP"
|
||||
|
||||
@ -143,7 +143,7 @@ Main loop manages timers, jobs and polling sockets\&.
|
||||
|
||||
.PP
|
||||
An opaque data type representing the main loop\&.
|
||||
.SS "typedef void(* \fBqb_loop_timer_dispatch_fn\fP)(void *data)"
|
||||
.SS "typedef void(* qb_loop_timer_dispatch_fn)(void *data)"
|
||||
|
||||
.SS "typedef uint64_t \fBqb_loop_timer_handle\fP"
|
||||
|
||||
@ -165,7 +165,7 @@ Priorites for jobs, timers & poll\&.
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "\fBqb_loop_t\fP* \fBqb_loop_create\fP (void)"
|
||||
.SS "\fBqb_loop_t\fP* qb_loop_create (void)"
|
||||
|
||||
.PP
|
||||
Create a new main loop\&. \fBReturns:\fP
|
||||
@ -174,9 +174,9 @@ loop instance\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_loop_destroy\fP (struct qb_loop *l)"
|
||||
.SS "void qb_loop_destroy (struct qb_loop *l)"
|
||||
|
||||
.SS "int32_t \fBqb_loop_job_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)"
|
||||
.SS "int32_t qb_loop_job_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)"
|
||||
|
||||
.PP
|
||||
Add a job to the mainloop\&. This is run in the next cycle of the loop\&.
|
||||
@ -203,7 +203,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_job_del\fP (struct qb_loop *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)"
|
||||
.SS "int32_t qb_loop_job_del (struct qb_loop *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)"
|
||||
|
||||
.PP
|
||||
Delete a job from the mainloop\&. This will try to delete the job if it hasn't run yet\&.
|
||||
@ -230,7 +230,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_poll_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)"
|
||||
.SS "int32_t qb_loop_poll_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)"
|
||||
|
||||
.PP
|
||||
Add a poll job to the mainloop\&. \fBNote:\fP
|
||||
@ -259,7 +259,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_poll_del\fP (\fBqb_loop_t\fP *l, int32_tfd)"
|
||||
.SS "int32_t qb_loop_poll_del (\fBqb_loop_t\fP *l, int32_tfd)"
|
||||
|
||||
.PP
|
||||
Delete a poll job\&. \fBParameters:\fP
|
||||
@ -275,7 +275,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_poll_low_fds_event_set\fP (\fBqb_loop_t\fP *l, \fBqb_loop_poll_low_fds_event_fn\fPfn)"
|
||||
.SS "int32_t qb_loop_poll_low_fds_event_set (\fBqb_loop_t\fP *l, \fBqb_loop_poll_low_fds_event_fn\fPfn)"
|
||||
|
||||
.PP
|
||||
Set a callback to receive events on file descriptors getting low\&. \fBParameters:\fP
|
||||
@ -291,7 +291,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_poll_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)"
|
||||
.SS "int32_t qb_loop_poll_mod (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)"
|
||||
|
||||
.PP
|
||||
Modify a poll job\&. \fBParameters:\fP
|
||||
@ -315,7 +315,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_loop_run\fP (\fBqb_loop_t\fP *l)"
|
||||
.SS "void qb_loop_run (\fBqb_loop_t\fP *l)"
|
||||
|
||||
.PP
|
||||
Run the main loop\&. \fBParameters:\fP
|
||||
@ -324,7 +324,7 @@ Run the main loop\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_signal_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsignal, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fP *handle)"
|
||||
.SS "int32_t qb_loop_signal_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsig, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fP *handle)"
|
||||
|
||||
.PP
|
||||
Add a signal job\&. Get a callback on this signal (not in the context of the signal)\&.
|
||||
@ -335,7 +335,7 @@ Add a signal job\&. Get a callback on this signal (not in the context of the sig
|
||||
.br
|
||||
\fIp\fP the priority
|
||||
.br
|
||||
\fIsignal\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&.
|
||||
\fIsig\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&.
|
||||
.br
|
||||
\fIdata\fP user data passed into the dispatch function
|
||||
.br
|
||||
@ -350,7 +350,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_signal_del\fP (\fBqb_loop_t\fP *l, \fBqb_loop_signal_handle\fPhandle)"
|
||||
.SS "int32_t qb_loop_signal_del (\fBqb_loop_t\fP *l, \fBqb_loop_signal_handle\fPhandle)"
|
||||
|
||||
.PP
|
||||
Delete the signal job\&. \fBParameters:\fP
|
||||
@ -366,7 +366,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_signal_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsignal, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fPhandle)"
|
||||
.SS "int32_t qb_loop_signal_mod (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsig, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fPhandle)"
|
||||
|
||||
.PP
|
||||
Modify the signal job\&. \fBParameters:\fP
|
||||
@ -375,7 +375,7 @@ Modify the signal job\&. \fBParameters:\fP
|
||||
.br
|
||||
\fIp\fP the priority
|
||||
.br
|
||||
\fIsignal\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&.
|
||||
\fIsig\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&.
|
||||
.br
|
||||
\fIdata\fP user data passed into the dispatch function
|
||||
.br
|
||||
@ -390,7 +390,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_loop_stop\fP (\fBqb_loop_t\fP *l)"
|
||||
.SS "void qb_loop_stop (\fBqb_loop_t\fP *l)"
|
||||
|
||||
.PP
|
||||
Stop the main loop\&. \fBParameters:\fP
|
||||
@ -399,7 +399,7 @@ Stop the main loop\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_timer_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, uint64_tnsec_duration, void *data, \fBqb_loop_timer_dispatch_fn\fPdispatch_fn, \fBqb_loop_timer_handle\fP *timer_handle_out)"
|
||||
.SS "int32_t qb_loop_timer_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, uint64_tnsec_duration, void *data, \fBqb_loop_timer_dispatch_fn\fPdispatch_fn, \fBqb_loop_timer_handle\fP *timer_handle_out)"
|
||||
|
||||
.PP
|
||||
Add a timer to the mainloop\&. \fBNote:\fP
|
||||
@ -428,7 +428,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_timer_del\fP (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)"
|
||||
.SS "int32_t qb_loop_timer_del (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)"
|
||||
|
||||
.PP
|
||||
Delete a timer that is still outstanding\&. \fBParameters:\fP
|
||||
@ -444,7 +444,7 @@ status (0 == ok, -errno == failure)
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "uint64_t \fBqb_loop_timer_expire_time_get\fP (struct qb_loop *l, \fBqb_loop_timer_handle\fPth)"
|
||||
.SS "uint64_t qb_loop_timer_expire_time_get (struct qb_loop *l, \fBqb_loop_timer_handle\fPth)"
|
||||
|
||||
.PP
|
||||
Get the time remaining before it expires\&. \fBNote:\fP
|
||||
@ -465,7 +465,7 @@ nano seconds left
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_loop_timer_is_running\fP (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)"
|
||||
.SS "int32_t qb_loop_timer_is_running (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)"
|
||||
|
||||
.PP
|
||||
Check to see if a timer that is still outstanding\&. \fBParameters:\fP
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbmap.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbmap.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -14,7 +14,7 @@ This provides a map interface to a Patricia trie, hashtable or skiplist\&.
|
||||
\fC#include <unistd\&.h>\fP
|
||||
.br
|
||||
|
||||
.SS "Defines"
|
||||
.SS "Macros"
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
@ -137,13 +137,13 @@ The hashtable is NOT ordered, but ptrie and skiplist are\&.
|
||||
Below is a simple example of how to iterate over a map\&.
|
||||
.PP
|
||||
.nf
|
||||
const char *p;
|
||||
void *data;
|
||||
qb_map_iter_t *it = qb_map_iter_create(m);
|
||||
for (p = qb_map_iter_next(it, &data); p; p = qb_map_iter_next(it, &data)) {
|
||||
printf('%s > %s\n', p, (char*) data);
|
||||
}
|
||||
qb_map_iter_free(it);
|
||||
const char *p;
|
||||
void *data;
|
||||
qb_map_iter_t *it = qb_map_iter_create(m);
|
||||
for (p = qb_map_iter_next(it, &data); p; p = qb_map_iter_next(it, &data)) {
|
||||
printf('%s > %s\n', p, (char*) data);
|
||||
}
|
||||
qb_map_iter_free(it);
|
||||
|
||||
.fi
|
||||
.PP
|
||||
@ -152,7 +152,7 @@ Below is a simple example of how to iterate over a map\&.
|
||||
Deletion of items within the iterator is supported\&. But note do not free the item memory in the iterator\&. If you need to free the data items then register for a notifier and free the memory there\&. This is required as the items are reference counted\&.
|
||||
.PP
|
||||
.nf
|
||||
qb_map_notify_add(m, NULL, my_map_free_handler,
|
||||
qb_map_notify_add(m, NULL, my_map_free_handler,
|
||||
QB_MAP_NOTIFY_FREE, NULL);
|
||||
|
||||
.fi
|
||||
@ -180,18 +180,18 @@ The ptrie supports prefixes in the iterator:
|
||||
.PP
|
||||
.PP
|
||||
.nf
|
||||
it = qb_map_pref_iter_create(m, 'aa');
|
||||
while ((p = qb_map_iter_next(it, &data)) != NULL) {
|
||||
printf('%s > %s\n', p, (char*)data);
|
||||
}
|
||||
qb_map_iter_free(it);
|
||||
it = qb_map_pref_iter_create(m, 'aa');
|
||||
while ((p = qb_map_iter_next(it, &data)) != NULL) {
|
||||
printf('%s > %s\n', p, (char*)data);
|
||||
}
|
||||
qb_map_iter_free(it);
|
||||
.fi
|
||||
.PP
|
||||
.PP
|
||||
The ptrie also supports prefixes in notifications: (remember to pass QB_MAP_NOTIFY_RECURSIVE into the notify_add\&.
|
||||
.PP
|
||||
.nf
|
||||
qb_map_notify_add(m, 'root', my_map_notification,
|
||||
qb_map_notify_add(m, 'root', my_map_notification,
|
||||
(QB_MAP_NOTIFY_INSERTED|
|
||||
QB_MAP_NOTIFY_DELETED|
|
||||
QB_MAP_NOTIFY_REPLACED|
|
||||
@ -201,17 +201,17 @@ The ptrie also supports prefixes in notifications: (remember to pass QB_MAP_NOTI
|
||||
.fi
|
||||
.PP
|
||||
|
||||
.SH "Define Documentation"
|
||||
.SH "Macro Definition Documentation"
|
||||
.PP
|
||||
.SS "#define \fBQB_MAP_NOTIFY_DELETED\fP 1"
|
||||
.SS "#define QB_MAP_NOTIFY_DELETED 1"
|
||||
|
||||
.SS "#define \fBQB_MAP_NOTIFY_FREE\fP 16"
|
||||
.SS "#define QB_MAP_NOTIFY_FREE 16"
|
||||
|
||||
.SS "#define \fBQB_MAP_NOTIFY_INSERTED\fP 4"
|
||||
.SS "#define QB_MAP_NOTIFY_INSERTED 4"
|
||||
|
||||
.SS "#define \fBQB_MAP_NOTIFY_RECURSIVE\fP 8"
|
||||
.SS "#define QB_MAP_NOTIFY_RECURSIVE 8"
|
||||
|
||||
.SS "#define \fBQB_MAP_NOTIFY_REPLACED\fP 2"
|
||||
.SS "#define QB_MAP_NOTIFY_REPLACED 2"
|
||||
|
||||
.SH "Typedef Documentation"
|
||||
.PP
|
||||
@ -219,17 +219,17 @@ The ptrie also supports prefixes in notifications: (remember to pass QB_MAP_NOTI
|
||||
|
||||
.PP
|
||||
This is an opaque data type representing an iterator instance\&.
|
||||
.SS "typedef void(* \fBqb_map_notify_fn\fP)(uint32_t event, char *key, void *old_value, void *value, void *user_data)"
|
||||
.SS "typedef void(* qb_map_notify_fn)(uint32_t event, char *key, void *old_value, void *value, void *user_data)"
|
||||
|
||||
.SS "typedef struct qb_map \fBqb_map_t\fP"
|
||||
|
||||
.PP
|
||||
This is an opaque data type representing an instance of a map\&.
|
||||
.SS "typedef int32_t(* \fBqb_map_transverse_fn\fP)(const char *key, void *value, void *user_data)"
|
||||
.SS "typedef int32_t(* qb_map_transverse_fn)(const char *key, void *value, void *user_data)"
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "\fBqb_map_t\fP* \fBqb_hashtable_create\fP (size_tmax_size)"
|
||||
.SS "\fBqb_map_t\fP* qb_hashtable_create (size_tmax_size)"
|
||||
|
||||
.PP
|
||||
Create an unsorted map based on a hashtable\&. \fBParameters:\fP
|
||||
@ -243,19 +243,19 @@ the map instance
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "size_t \fBqb_map_count_get\fP (\fBqb_map_t\fP *map)"
|
||||
.SS "size_t qb_map_count_get (\fBqb_map_t\fP *map)"
|
||||
|
||||
.PP
|
||||
Get the number of items in the map\&.
|
||||
.SS "void \fBqb_map_destroy\fP (\fBqb_map_t\fP *map)"
|
||||
.SS "void qb_map_destroy (\fBqb_map_t\fP *map)"
|
||||
|
||||
.PP
|
||||
Destroy the map, removes all the items from the map\&.
|
||||
.SS "void \fBqb_map_foreach\fP (\fBqb_map_t\fP *map, \fBqb_map_transverse_fn\fPfunc, void *user_data)"
|
||||
.SS "void qb_map_foreach (\fBqb_map_t\fP *map, \fBqb_map_transverse_fn\fPfunc, void *user_data)"
|
||||
|
||||
.PP
|
||||
Calls the given function for each of the key/value pairs in the map\&. The function is passed the key and value of each pair, and the given data parameter\&. The map is traversed in sorted order\&.
|
||||
.SS "void* \fBqb_map_get\fP (\fBqb_map_t\fP *map, const char *key)"
|
||||
.SS "void* qb_map_get (\fBqb_map_t\fP *map, const char *key)"
|
||||
|
||||
.PP
|
||||
Gets the value corresponding to the given key\&. \fBReturn values:\fP
|
||||
@ -266,11 +266,11 @@ Gets the value corresponding to the given key\&. \fBReturn values:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "\fBqb_map_iter_t\fP* \fBqb_map_iter_create\fP (\fBqb_map_t\fP *map)"
|
||||
.SS "\fBqb_map_iter_t\fP* qb_map_iter_create (\fBqb_map_t\fP *map)"
|
||||
|
||||
.PP
|
||||
Create an iterator\&.
|
||||
.SS "void \fBqb_map_iter_free\fP (\fBqb_map_iter_t\fP *i)"
|
||||
.SS "void qb_map_iter_free (\fBqb_map_iter_t\fP *i)"
|
||||
|
||||
.PP
|
||||
free the iterator \fBParameters:\fP
|
||||
@ -279,7 +279,7 @@ free the iterator \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "const char* \fBqb_map_iter_next\fP (\fBqb_map_iter_t\fP *i, void **value)"
|
||||
.SS "const char* qb_map_iter_next (\fBqb_map_iter_t\fP *i, void **value)"
|
||||
|
||||
.PP
|
||||
Get the next item\&. \fBParameters:\fP
|
||||
@ -297,7 +297,7 @@ Get the next item\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_map_notify_add\fP (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)"
|
||||
.SS "int32_t qb_map_notify_add (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)"
|
||||
|
||||
.PP
|
||||
Add a notifier to the map\&. \fBParameters:\fP
|
||||
@ -328,7 +328,7 @@ you can use key prefixes with trie maps\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_map_notify_del\fP (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents)"
|
||||
.SS "int32_t qb_map_notify_del (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents)"
|
||||
|
||||
.PP
|
||||
Delete a notifier from the map\&. \fBNote:\fP
|
||||
@ -355,7 +355,7 @@ the key,fn and events must match those you added\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_map_notify_del_2\fP (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)"
|
||||
.SS "int32_t qb_map_notify_del_2 (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)"
|
||||
|
||||
.PP
|
||||
Delete a notifier from the map (including the userdata)\&. \fBNote:\fP
|
||||
@ -384,7 +384,7 @@ the key, fn, events and userdata must match those you added\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "\fBqb_map_iter_t\fP* \fBqb_map_pref_iter_create\fP (\fBqb_map_t\fP *map, const char *prefix)"
|
||||
.SS "\fBqb_map_iter_t\fP* qb_map_pref_iter_create (\fBqb_map_t\fP *map, const char *prefix)"
|
||||
|
||||
.PP
|
||||
Create a prefix iterator\&. This will iterate over all items with the given prefix\&.
|
||||
@ -395,15 +395,15 @@ this is only supported by the trie\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_map_put\fP (\fBqb_map_t\fP *map, const char *key, const void *value)"
|
||||
.SS "void qb_map_put (\fBqb_map_t\fP *map, const char *key, const void *value)"
|
||||
|
||||
.PP
|
||||
Inserts a new key and value into a qb_map_t\&. If the key already exists in the qb_map_t, it gets replaced by the new key\&.
|
||||
.SS "int32_t \fBqb_map_rm\fP (\fBqb_map_t\fP *map, const char *key)"
|
||||
.SS "int32_t qb_map_rm (\fBqb_map_t\fP *map, const char *key)"
|
||||
|
||||
.PP
|
||||
Removes a key/value pair from a map\&.
|
||||
.SS "\fBqb_map_t\fP* \fBqb_skiplist_create\fP (void)"
|
||||
.SS "\fBqb_map_t\fP* qb_skiplist_create (void)"
|
||||
|
||||
.PP
|
||||
Create a sorted map using a skiplist\&. \fBReturns:\fP
|
||||
@ -412,11 +412,11 @@ the map instance
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "\fBqb_map_t\fP* \fBqb_trie_create\fP (void)"
|
||||
.SS "\fBqb_map_t\fP* qb_trie_create (void)"
|
||||
|
||||
.PP
|
||||
Create a sorted map using a Patricia trie or 'Radix tree'\&.
|
||||
.SS "void \fBqb_trie_dump\fP (\fBqb_map_t\fP *m)"
|
||||
.SS "void qb_trie_dump (\fBqb_map_t\fP *m)"
|
||||
|
||||
.PP
|
||||
print out the nodes in the trie (for debug purposes)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH "qbutil.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*-
|
||||
.TH "qbutil.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
@ -15,7 +15,7 @@ qbutil.h \-
|
||||
\fC#include <qb/qbdefs\&.h>\fP
|
||||
.br
|
||||
|
||||
.SS "Defines"
|
||||
.SS "Macros"
|
||||
|
||||
.in +1c
|
||||
.ti -1c
|
||||
@ -180,21 +180,21 @@ These are some convience functions used throughout libqb\&.
|
||||
|
||||
.PP
|
||||
.nf
|
||||
uint64_t elapsed1;
|
||||
uint64_t elapsed2;
|
||||
qb_util_stopwatch_t *sw = qb_util_stopwatch_create();
|
||||
|
||||
qb_util_stopwatch_start(sw);
|
||||
|
||||
usleep(sometime);
|
||||
qb_util_stopwatch_stop(sw);
|
||||
elapsed1 = qb_util_stopwatch_us_elapsed_get(sw);
|
||||
|
||||
usleep(somemoretime);
|
||||
qb_util_stopwatch_stop(sw);
|
||||
elapsed2 = qb_util_stopwatch_us_elapsed_get(sw);
|
||||
|
||||
qb_util_stopwatch_free(sw);
|
||||
uint64_t elapsed1;
|
||||
uint64_t elapsed2;
|
||||
qb_util_stopwatch_t *sw = qb_util_stopwatch_create();
|
||||
|
||||
qb_util_stopwatch_start(sw);
|
||||
|
||||
usleep(sometime);
|
||||
qb_util_stopwatch_stop(sw);
|
||||
elapsed1 = qb_util_stopwatch_us_elapsed_get(sw);
|
||||
|
||||
usleep(somemoretime);
|
||||
qb_util_stopwatch_stop(sw);
|
||||
elapsed2 = qb_util_stopwatch_us_elapsed_get(sw);
|
||||
|
||||
qb_util_stopwatch_free(sw);
|
||||
|
||||
.fi
|
||||
.PP
|
||||
@ -207,44 +207,44 @@ Setup a stopwatch with space for 3 splits\&.
|
||||
.PP
|
||||
.PP
|
||||
.nf
|
||||
uint64_t split;
|
||||
qb_util_stopwatch_t *sw = qb_util_stopwatch_create();
|
||||
|
||||
qb_util_stopwatch_split_ctl(sw, 3, 0);
|
||||
qb_util_stopwatch_start(sw);
|
||||
|
||||
usleep(sometime);
|
||||
qb_util_stopwatch_split(sw);
|
||||
|
||||
usleep(somemoretime);
|
||||
qb_util_stopwatch_split(sw);
|
||||
|
||||
usleep(somemoretime);
|
||||
qb_util_stopwatch_split(sw);
|
||||
|
||||
idx = qb_util_stopwatch_split_last(sw);
|
||||
do {
|
||||
split = qb_util_stopwatch_time_split_get(sw, idx, idx);
|
||||
qb_log(LOG_INFO, 'split %d is %'PRIu64'', last, split);
|
||||
idx--;
|
||||
} while (split > 0);
|
||||
|
||||
split = qb_util_stopwatch_time_split_get(sw, 2, 1);
|
||||
qb_log(LOG_INFO, 'time between second and third split is %'PRIu64'', split);
|
||||
|
||||
qb_util_stopwatch_free(sw);
|
||||
uint64_t split;
|
||||
qb_util_stopwatch_t *sw = qb_util_stopwatch_create();
|
||||
|
||||
qb_util_stopwatch_split_ctl(sw, 3, 0);
|
||||
qb_util_stopwatch_start(sw);
|
||||
|
||||
usleep(sometime);
|
||||
qb_util_stopwatch_split(sw);
|
||||
|
||||
usleep(somemoretime);
|
||||
qb_util_stopwatch_split(sw);
|
||||
|
||||
usleep(somemoretime);
|
||||
qb_util_stopwatch_split(sw);
|
||||
|
||||
idx = qb_util_stopwatch_split_last(sw);
|
||||
do {
|
||||
split = qb_util_stopwatch_time_split_get(sw, idx, idx);
|
||||
qb_log(LOG_INFO, 'split %d is %'PRIu64'', last, split);
|
||||
idx--;
|
||||
} while (split > 0);
|
||||
|
||||
split = qb_util_stopwatch_time_split_get(sw, 2, 1);
|
||||
qb_log(LOG_INFO, 'time between second and third split is %'PRIu64'', split);
|
||||
|
||||
qb_util_stopwatch_free(sw);
|
||||
.fi
|
||||
.PP
|
||||
|
||||
.SH "Define Documentation"
|
||||
.SH "Macro Definition Documentation"
|
||||
.PP
|
||||
.SS "#define \fBQB_UTIL_SW_OVERWRITE\fP 0x01"
|
||||
.SS "#define QB_UTIL_SW_OVERWRITE 0x01"
|
||||
|
||||
.SH "Typedef Documentation"
|
||||
.PP
|
||||
.SS "typedef struct qb_thread_lock_s \fBqb_thread_lock_t\fP"
|
||||
|
||||
.SS "typedef void(* \fBqb_util_log_fn_t\fP)(const char *file_name, int32_t file_line, int32_t severity, const char *msg)"
|
||||
.SS "typedef void(* qb_util_log_fn_t)(const char *file_name, int32_t file_line, int32_t severity, const char *msg)"
|
||||
|
||||
.SS "typedef struct qb_util_stopwatch \fBqb_util_stopwatch_t\fP"
|
||||
|
||||
@ -264,15 +264,15 @@ QB_THREAD_LOCK_SHORT is a short term lock (spinlock if available on your system)
|
||||
|
||||
.SH "Function Documentation"
|
||||
.PP
|
||||
.SS "char* \fBqb_strerror_r\fP (interrnum, char *buf, size_tbuflen)"
|
||||
.SS "char* qb_strerror_r (interrnum, char *buf, size_tbuflen)"
|
||||
|
||||
.PP
|
||||
strerror_r replacement\&.
|
||||
.SS "int32_t \fBqb_thread_lock\fP (\fBqb_thread_lock_t\fP *tl)"
|
||||
.SS "int32_t qb_thread_lock (\fBqb_thread_lock_t\fP *tl)"
|
||||
|
||||
.PP
|
||||
Calls either pthread_mutex_lock() or pthread_spin_lock()\&.
|
||||
.SS "\fBqb_thread_lock_t\fP* \fBqb_thread_lock_create\fP (\fBqb_thread_lock_type_t\fPtype)"
|
||||
.SS "\fBqb_thread_lock_t\fP* qb_thread_lock_create (\fBqb_thread_lock_type_t\fPtype)"
|
||||
|
||||
.PP
|
||||
Create a new lock of the given type\&. \fBParameters:\fP
|
||||
@ -286,19 +286,19 @@ pointer to qb_thread_lock_type_t or NULL on error\&.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_thread_lock_destroy\fP (\fBqb_thread_lock_t\fP *tl)"
|
||||
.SS "int32_t qb_thread_lock_destroy (\fBqb_thread_lock_t\fP *tl)"
|
||||
|
||||
.PP
|
||||
Calls either pthread_mutex_destro() or pthread_spin_destroy()\&.
|
||||
.SS "int32_t \fBqb_thread_trylock\fP (\fBqb_thread_lock_t\fP *tl)"
|
||||
.SS "int32_t qb_thread_trylock (\fBqb_thread_lock_t\fP *tl)"
|
||||
|
||||
.PP
|
||||
Calls either pthread_mutex_trylock() or pthread_spin_trylock()\&.
|
||||
.SS "int32_t \fBqb_thread_unlock\fP (\fBqb_thread_lock_t\fP *tl)"
|
||||
.SS "int32_t qb_thread_unlock (\fBqb_thread_lock_t\fP *tl)"
|
||||
|
||||
.PP
|
||||
Calls either pthread_mutex_unlock() or pthread_spin_unlock\&.
|
||||
.SS "void \fBqb_timespec_add_ms\fP (struct timespec *ts, int32_tms)"
|
||||
.SS "void qb_timespec_add_ms (struct timespec *ts, int32_tms)"
|
||||
|
||||
.PP
|
||||
Add milliseconds onto the timespec\&. \fBParameters:\fP
|
||||
@ -309,35 +309,35 @@ Add milliseconds onto the timespec\&. \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "uint64_t \fBqb_util_nano_current_get\fP (void)"
|
||||
.SS "uint64_t qb_util_nano_current_get (void)"
|
||||
|
||||
.PP
|
||||
Get the current number of nano secounds produced by the systems incrementing clock (CLOCK_MONOTOMIC if available)\&.
|
||||
.SS "uint64_t \fBqb_util_nano_from_epoch_get\fP (void)"
|
||||
.SS "uint64_t qb_util_nano_from_epoch_get (void)"
|
||||
|
||||
.PP
|
||||
Get the time in nano seconds since epoch\&.
|
||||
.SS "uint64_t \fBqb_util_nano_monotonic_hz\fP (void)"
|
||||
.SS "uint64_t qb_util_nano_monotonic_hz (void)"
|
||||
|
||||
.PP
|
||||
Get the frequence of the clock used in \fBqb_util_nano_current_get()\fP\&.
|
||||
.SS "void \fBqb_util_set_log_function\fP (\fBqb_util_log_fn_t\fPfn)"
|
||||
.SS "void qb_util_set_log_function (\fBqb_util_log_fn_t\fPfn)"
|
||||
|
||||
.PP
|
||||
Use this function to output libqb internal log message as you wish\&.
|
||||
.SS "\fBqb_util_stopwatch_t\fP* \fBqb_util_stopwatch_create\fP (void)"
|
||||
.SS "\fBqb_util_stopwatch_t\fP* qb_util_stopwatch_create (void)"
|
||||
|
||||
.PP
|
||||
Create a Stopwatch (to time operations)
|
||||
.SS "void \fBqb_util_stopwatch_free\fP (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
.SS "void qb_util_stopwatch_free (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
|
||||
.PP
|
||||
Free the stopwatch\&.
|
||||
.SS "float \fBqb_util_stopwatch_sec_elapsed_get\fP (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
.SS "float qb_util_stopwatch_sec_elapsed_get (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
|
||||
.PP
|
||||
Get the elapsed time in seconds\&. (it must have been started and stopped)\&.
|
||||
.SS "uint64_t \fBqb_util_stopwatch_split\fP (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
.SS "uint64_t qb_util_stopwatch_split (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
|
||||
.PP
|
||||
Create a new time split (or lap time) \fBParameters:\fP
|
||||
@ -353,7 +353,7 @@ Create a new time split (or lap time) \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "int32_t \fBqb_util_stopwatch_split_ctl\fP (\fBqb_util_stopwatch_t\fP *sw, uint32_tmax_splits, uint32_toptions)"
|
||||
.SS "int32_t qb_util_stopwatch_split_ctl (\fBqb_util_stopwatch_t\fP *sw, uint32_tmax_splits, uint32_toptions)"
|
||||
\fBParameters:\fP
|
||||
.RS 4
|
||||
\fIsw\fP the stopwatch
|
||||
@ -371,7 +371,7 @@ Create a new time split (or lap time) \fBParameters:\fP
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "uint32_t \fBqb_util_stopwatch_split_last\fP (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
.SS "uint32_t qb_util_stopwatch_split_last (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
|
||||
.PP
|
||||
Get the last split index to be used by \fBqb_util_stopwatch_time_split_get()\fP \fBNote:\fP
|
||||
@ -390,15 +390,15 @@ the last entry index
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "void \fBqb_util_stopwatch_start\fP (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
.SS "void qb_util_stopwatch_start (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
|
||||
.PP
|
||||
Start the stopwatch\&. This also acts as a reset\&. Essentially it sets the starting time and clears the splits\&.
|
||||
.SS "void \fBqb_util_stopwatch_stop\fP (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
.SS "void qb_util_stopwatch_stop (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
|
||||
.PP
|
||||
Stop the stopwatch\&. This just allows you to get the elapsed time\&. So you can call this multiple times\&. Do not call \fBqb_util_stopwatch_start()\fP unless you want to reset the stopwatch\&.
|
||||
.SS "uint64_t \fBqb_util_stopwatch_time_split_get\fP (\fBqb_util_stopwatch_t\fP *sw, uint32_treceint, uint32_tolder)"
|
||||
.SS "uint64_t qb_util_stopwatch_time_split_get (\fBqb_util_stopwatch_t\fP *sw, uint32_treceint, uint32_tolder)"
|
||||
|
||||
.PP
|
||||
Read the time split (in us) from 'receint' to 'older'\&. If older == receint then the cumulated split will be returned (from the stopwatch start)\&.
|
||||
@ -420,11 +420,11 @@ Read the time split (in us) from 'receint' to 'older'\&. If older == receint the
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SS "uint64_t \fBqb_util_stopwatch_us_elapsed_get\fP (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
.SS "uint64_t qb_util_stopwatch_us_elapsed_get (\fBqb_util_stopwatch_t\fP *sw)"
|
||||
|
||||
.PP
|
||||
Get the elapsed time in micro seconds\&. (it must have been started and stopped)\&.
|
||||
.SS "void \fBqb_util_timespec_from_epoch_get\fP (struct timespec *ts)"
|
||||
.SS "void qb_util_timespec_from_epoch_get (struct timespec *ts)"
|
||||
|
||||
.PP
|
||||
Get the time in timespec since epoch\&. \fBParameters:\fP
|
||||
|
||||
59
docs/man8/qb-blackbox.8
Normal file
59
docs/man8/qb-blackbox.8
Normal file
@ -0,0 +1,59 @@
|
||||
.\"/*
|
||||
.\" * Copyright (C) 2012 Red Hat, Inc.
|
||||
.\" *
|
||||
.\" * Author: Angus Salkeld <asalkeld@redhat.com>
|
||||
.\" *
|
||||
.\" * This file is part of libqb.
|
||||
.\" *
|
||||
.\" * libqb is free software: you can redistribute it and/or modify
|
||||
.\" * it under the terms of the GNU Lesser General Public License as published by
|
||||
.\" * the Free Software Foundation, either version 2.1 of the License, or
|
||||
.\" * (at your option) any later version.
|
||||
.\" *
|
||||
.\" * libqb is distributed in the hope that it will be useful,
|
||||
.\" * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
.\" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
.\" * GNU Lesser General Public License for more details.
|
||||
.\" *
|
||||
.\" * You should have received a copy of the GNU Lesser General Public License
|
||||
.\" * along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
.\" */
|
||||
.TH QB-BLACKBOX 8 2012-05-28
|
||||
.SH NAME
|
||||
qb-blackbox \- Display "flight data" from the "blackbox".
|
||||
.SH SYNOPSIS
|
||||
.B "qb-blackbox <blackbox files>..."
|
||||
.SH DESCRIPTION
|
||||
.B qb-blackbox
|
||||
Print out the logs (including debug logs) that were recorded using libqb's blackbox.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
Get info to help developers diagnose a crash.
|
||||
.br
|
||||
$ qb-blackbox /var/lib/corosync/fdata
|
||||
.br
|
||||
Dumping the contents of /var/lib/corosync/fdata
|
||||
.br
|
||||
Mar 23 20:58:57 message_handler_orf_token():3677 install seq 0 aru 0 high seq received 0
|
||||
.br
|
||||
Mar 23 20:58:57 message_handler_orf_token():3696 retrans flag count 4 token aru 0 install seq 0 aru 0 0
|
||||
.br
|
||||
Mar 23 20:58:57 old_ring_state_reset():1487 Resetting old ring state
|
||||
.br
|
||||
Mar 23 20:58:57 deliver_messages_from_recovery_to_regular():1693 recovery to regular 1-0
|
||||
.br
|
||||
Mar 23 20:58:57 memb_state_operational_enter():1779 Delivering to app 1 to 0
|
||||
.br
|
||||
Mar 23 20:58:57 sync_abort():594 ENTERING sync_abort()
|
||||
.br
|
||||
Mar 23 20:58:57 sync_save_transitional():586 ENTERING sync_save_transitional()
|
||||
.br
|
||||
Mar 23 20:58:57 member_object_joined():301 Member joined: r(0) ip(192.168.122.1)
|
||||
.br
|
||||
Mar 23 20:58:57 sync_abort():594 ENTERING sync_abort()
|
||||
.br
|
||||
.SH SEE ALSO
|
||||
.BR qblog.h (3),
|
||||
.SH AUTHOR
|
||||
Angus Salkeld
|
||||
.PP
|
||||
@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
MAINTAINERCLEANFILES = Makefiles.in
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
EXTRA_DIST =
|
||||
CLEANFILES =
|
||||
|
||||
@ -25,27 +25,27 @@ noinst_PROGRAMS = mapnotify simplelog tcpclient tcpserver ipcclient ipcserver
|
||||
|
||||
mapnotify_SOURCES = mapnotify.c $(top_builddir)/include/qb/qbmap.h
|
||||
mapnotify_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
mapnotify_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
mapnotify_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
simplelog_SOURCES = simplelog.c $(top_builddir)/include/qb/qblog.h
|
||||
simplelog_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
simplelog_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
simplelog_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
tcpclient_SOURCES = tcpclient.c $(top_builddir)/include/qb/qbloop.h
|
||||
tcpclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
tcpclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
tcpclient_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
tcpserver_SOURCES = tcpserver.c $(top_builddir)/include/qb/qbloop.h
|
||||
tcpserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
tcpserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
tcpserver_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
ipcclient_SOURCES = ipcclient.c $(top_builddir)/include/qb/qbloop.h \
|
||||
$(top_builddir)/include/qb/qbipcc.h
|
||||
ipcclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
ipcclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
ipcclient_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
ipcserver_SOURCES = ipcserver.c $(top_builddir)/include/qb/qbloop.h \
|
||||
$(top_builddir)/include/qb/qbipcs.h
|
||||
ipcserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \
|
||||
$(GLIB_CFLAGS)
|
||||
ipcserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
ipcserver_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
|
||||
@ -54,34 +54,29 @@ CONFIG_CLEAN_VPATH_FILES =
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
am_ipcclient_OBJECTS = ipcclient-ipcclient.$(OBJEXT)
|
||||
ipcclient_OBJECTS = $(am_ipcclient_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
ipcclient_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
ipcclient_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
am_ipcserver_OBJECTS = ipcserver-ipcserver.$(OBJEXT)
|
||||
ipcserver_OBJECTS = $(am_ipcserver_OBJECTS)
|
||||
ipcserver_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la $(am__DEPENDENCIES_1)
|
||||
am__DEPENDENCIES_1 =
|
||||
ipcserver_DEPENDENCIES = $(top_builddir)/lib/libqb.la \
|
||||
$(am__DEPENDENCIES_1)
|
||||
am_mapnotify_OBJECTS = mapnotify-mapnotify.$(OBJEXT)
|
||||
mapnotify_OBJECTS = $(am_mapnotify_OBJECTS)
|
||||
mapnotify_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
mapnotify_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am_simplelog_OBJECTS = simplelog-simplelog.$(OBJEXT)
|
||||
simplelog_OBJECTS = $(am_simplelog_OBJECTS)
|
||||
simplelog_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
simplelog_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am_tcpclient_OBJECTS = tcpclient-tcpclient.$(OBJEXT)
|
||||
tcpclient_OBJECTS = $(am_tcpclient_OBJECTS)
|
||||
tcpclient_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
tcpclient_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am_tcpserver_OBJECTS = tcpserver-tcpserver.$(OBJEXT)
|
||||
tcpserver_OBJECTS = $(am_tcpserver_OBJECTS)
|
||||
tcpserver_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
tcpserver_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
@ -161,7 +156,6 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_RT = @LIB_RT@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
@ -268,33 +262,33 @@ top_srcdir = @top_srcdir@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
MAINTAINERCLEANFILES = Makefiles.in
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
EXTRA_DIST =
|
||||
CLEANFILES =
|
||||
mapnotify_SOURCES = mapnotify.c $(top_builddir)/include/qb/qbmap.h
|
||||
mapnotify_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
mapnotify_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
mapnotify_LDADD = $(top_builddir)/lib/libqb.la
|
||||
simplelog_SOURCES = simplelog.c $(top_builddir)/include/qb/qblog.h
|
||||
simplelog_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
simplelog_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
simplelog_LDADD = $(top_builddir)/lib/libqb.la
|
||||
tcpclient_SOURCES = tcpclient.c $(top_builddir)/include/qb/qbloop.h
|
||||
tcpclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
tcpclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
tcpclient_LDADD = $(top_builddir)/lib/libqb.la
|
||||
tcpserver_SOURCES = tcpserver.c $(top_builddir)/include/qb/qbloop.h
|
||||
tcpserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
tcpserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
tcpserver_LDADD = $(top_builddir)/lib/libqb.la
|
||||
ipcclient_SOURCES = ipcclient.c $(top_builddir)/include/qb/qbloop.h \
|
||||
$(top_builddir)/include/qb/qbipcc.h
|
||||
|
||||
ipcclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
ipcclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
ipcclient_LDADD = $(top_builddir)/lib/libqb.la
|
||||
ipcserver_SOURCES = ipcserver.c $(top_builddir)/include/qb/qbloop.h \
|
||||
$(top_builddir)/include/qb/qbipcs.h
|
||||
|
||||
ipcserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \
|
||||
$(GLIB_CFLAGS)
|
||||
|
||||
ipcserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
ipcserver_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
@ -24,8 +24,15 @@
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qbipcc.h>
|
||||
#include <qb/qblog.h>
|
||||
|
||||
#define MAX_MSG_SIZE (8192)
|
||||
static int32_t do_benchmark = QB_FALSE;
|
||||
static int32_t use_events = QB_FALSE;
|
||||
static int alarm_notice;
|
||||
static qb_util_stopwatch_t *sw;
|
||||
#define ONE_MEG 1048576
|
||||
#define MAX_MSG_SIZE ONE_MEG
|
||||
static char data[ONE_MEG];
|
||||
|
||||
struct my_req {
|
||||
struct qb_ipc_request_header hdr;
|
||||
@ -37,22 +44,84 @@ struct my_res {
|
||||
char message[256];
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
static void sigalrm_handler (int num)
|
||||
{
|
||||
alarm_notice = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_benchmark(qb_ipcc_connection_t *conn, int write_size)
|
||||
{
|
||||
struct iovec iov[2];
|
||||
unsigned int res;
|
||||
struct qb_ipc_request_header hdr;
|
||||
int write_count = 0;
|
||||
float secs;
|
||||
|
||||
alarm_notice = 0;
|
||||
hdr.size = write_size;
|
||||
hdr.id = QB_IPC_MSG_USER_START + 1;
|
||||
|
||||
iov[0].iov_base = &hdr;
|
||||
iov[0].iov_len = sizeof(struct qb_ipc_request_header);
|
||||
|
||||
iov[1].iov_base = data;
|
||||
iov[1].iov_len = write_size - sizeof(struct qb_ipc_request_header);
|
||||
|
||||
alarm (10);
|
||||
|
||||
qb_util_stopwatch_start(sw);
|
||||
do {
|
||||
res = qb_ipcc_sendv(conn, iov, 2);
|
||||
if (res == write_size) {
|
||||
write_count++;
|
||||
}
|
||||
} while (alarm_notice == 0 && (res == write_size || res == -EAGAIN));
|
||||
if (res < 0) {
|
||||
perror("qb_ipcc_sendv");
|
||||
}
|
||||
qb_util_stopwatch_stop(sw);
|
||||
secs = qb_util_stopwatch_sec_elapsed_get(sw);
|
||||
|
||||
printf ("%5d messages sent ", write_count);
|
||||
printf ("%5d bytes per write ", write_size);
|
||||
printf ("%7.3f Seconds runtime ", secs);
|
||||
printf ("%9.3f TP/s ",
|
||||
((float)write_count) / secs);
|
||||
printf ("%7.3f MB/s.\n",
|
||||
((float)write_count) * ((float)write_size) / secs);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_throughput_benchmark(qb_ipcc_connection_t *conn)
|
||||
{
|
||||
ssize_t size = 64;
|
||||
int i;
|
||||
|
||||
signal (SIGALRM, sigalrm_handler);
|
||||
sw = qb_util_stopwatch_create();
|
||||
|
||||
for (i = 0; i < 10; i++) { /* number of repetitions - up to 50k */
|
||||
_benchmark (conn, size);
|
||||
signal (SIGALRM, sigalrm_handler);
|
||||
size *= 5;
|
||||
if (size >= (ONE_MEG - 100)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_echo(qb_ipcc_connection_t *conn)
|
||||
{
|
||||
qb_ipcc_connection_t *conn;
|
||||
int32_t rc;
|
||||
struct my_req req;
|
||||
struct my_res res;
|
||||
char *newline;
|
||||
int32_t rc;
|
||||
int32_t send_ten_events;
|
||||
|
||||
conn = qb_ipcc_connect("ipcserver", MAX_MSG_SIZE);
|
||||
if (conn == NULL) {
|
||||
perror("qb_ipcc_connect");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
while (1) {
|
||||
printf("SEND (q or Q to quit) : ");
|
||||
if (fgets(req.message, 256, stdin) == NULL) {
|
||||
continue;
|
||||
@ -70,21 +139,99 @@ main(int argc, char *argv[])
|
||||
rc = qb_ipcc_send(conn, &req, req.hdr.size);
|
||||
if (rc < 0) {
|
||||
perror("qb_ipcc_send");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
send_ten_events = (strcasecmp(req.message, "events") == 0);
|
||||
|
||||
if (rc > 0) {
|
||||
rc = qb_ipcc_recv(conn,
|
||||
&res,
|
||||
sizeof(res), -1);
|
||||
if (use_events && !send_ten_events) {
|
||||
printf("waiting for event recv\n");
|
||||
rc = qb_ipcc_event_recv(conn, &res, sizeof(res), -1);
|
||||
} else {
|
||||
printf("waiting for recv\n");
|
||||
rc = qb_ipcc_recv(conn, &res, sizeof(res), -1);
|
||||
}
|
||||
printf("recv %d\n", rc);
|
||||
if (rc < 0) {
|
||||
perror("qb_ipcc_recv");
|
||||
exit(0);
|
||||
}
|
||||
if (send_ten_events) {
|
||||
int32_t i;
|
||||
printf("waiting for 10 events\n");
|
||||
for (i = 0; i < 10; i++) {
|
||||
rc = qb_ipcc_event_recv(conn, &res, sizeof(res), -1);
|
||||
if (rc < 0) {
|
||||
perror("qb_ipcc_event_recv");
|
||||
} else {
|
||||
printf("got event %d rc:%d\n", i, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("Response[%d]: %s \n", res.hdr.id, res.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_usage(const char *name)
|
||||
{
|
||||
printf("usage: \n");
|
||||
printf("%s <options>\n", name);
|
||||
printf("\n");
|
||||
printf(" options:\n");
|
||||
printf("\n");
|
||||
printf(" -h show this help text\n");
|
||||
printf(" -b benchmark\n");
|
||||
printf(" -e use events instead of responses\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
qb_ipcc_connection_t *conn;
|
||||
const char *options = "eb";
|
||||
int32_t opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, options)) != -1) {
|
||||
switch (opt) {
|
||||
case 'b':
|
||||
do_benchmark = QB_TRUE;
|
||||
break;
|
||||
case 'e':
|
||||
use_events = QB_TRUE;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
show_usage(argv[0]);
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qb_log_init("ipcclient", LOG_USER, LOG_TRACE);
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_TRACE);
|
||||
qb_log_format_set(QB_LOG_STDERR, "%f:%l [%p] %b");
|
||||
qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
|
||||
conn = qb_ipcc_connect("ipcserver", MAX_MSG_SIZE);
|
||||
if (conn == NULL) {
|
||||
perror("qb_ipcc_connect");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (do_benchmark) {
|
||||
do_throughput_benchmark(conn);
|
||||
} else {
|
||||
do_echo(conn);
|
||||
}
|
||||
|
||||
qb_ipcc_disconnect(conn);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@ -34,11 +34,12 @@ static qb_array_t *gio_map;
|
||||
#endif /* HAVE_GLIB */
|
||||
|
||||
static int32_t use_glib = QB_FALSE;
|
||||
static int32_t use_events = QB_FALSE;
|
||||
static qb_loop_t *bms_loop;
|
||||
static qb_ipcs_service_t* s1;
|
||||
static qb_ipcs_service_t *s1;
|
||||
|
||||
static int32_t
|
||||
s1_connection_accept_fn(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
|
||||
s1_connection_accept_fn(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
|
||||
{
|
||||
#if 0
|
||||
if (uid == 0 && gid == 0) {
|
||||
@ -52,34 +53,33 @@ s1_connection_accept_fn(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
s1_connection_created_fn(qb_ipcs_connection_t *c)
|
||||
static void
|
||||
s1_connection_created_fn(qb_ipcs_connection_t * c)
|
||||
{
|
||||
struct qb_ipcs_stats srv_stats;
|
||||
|
||||
qb_ipcs_stats_get(s1, &srv_stats, QB_FALSE);
|
||||
qb_log(LOG_INFO, "Connection created (active:%d, closed:%d)",
|
||||
srv_stats.active_connections,
|
||||
srv_stats.closed_connections);
|
||||
srv_stats.active_connections, srv_stats.closed_connections);
|
||||
}
|
||||
|
||||
static void
|
||||
s1_connection_destroyed_fn(qb_ipcs_connection_t *c)
|
||||
static void
|
||||
s1_connection_destroyed_fn(qb_ipcs_connection_t * c)
|
||||
{
|
||||
qb_log(LOG_INFO, "Connection about to be freed");
|
||||
}
|
||||
|
||||
static int32_t
|
||||
s1_connection_closed_fn(qb_ipcs_connection_t *c)
|
||||
static int32_t
|
||||
s1_connection_closed_fn(qb_ipcs_connection_t * c)
|
||||
{
|
||||
struct qb_ipcs_connection_stats stats;
|
||||
struct qb_ipcs_stats srv_stats;
|
||||
|
||||
qb_ipcs_stats_get(s1, &srv_stats, QB_FALSE);
|
||||
qb_ipcs_connection_stats_get(c, &stats, QB_FALSE);
|
||||
qb_log(LOG_INFO, "Connection to pid:%d destroyed (active:%d, closed:%d)",
|
||||
stats.client_pid,
|
||||
srv_stats.active_connections,
|
||||
qb_log(LOG_INFO,
|
||||
"Connection to pid:%d destroyed (active:%d, closed:%d)",
|
||||
stats.client_pid, srv_stats.active_connections,
|
||||
srv_stats.closed_connections);
|
||||
|
||||
qb_log(LOG_DEBUG, " Requests %"PRIu64"", stats.requests);
|
||||
@ -92,36 +92,69 @@ s1_connection_closed_fn(qb_ipcs_connection_t *c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
s1_msg_process_fn(qb_ipcs_connection_t *c,
|
||||
void *data, size_t size)
|
||||
struct my_req {
|
||||
struct qb_ipc_request_header hdr;
|
||||
char message[256];
|
||||
};
|
||||
|
||||
static int32_t
|
||||
s1_msg_process_fn(qb_ipcs_connection_t * c, void *data, size_t size)
|
||||
{
|
||||
struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header *)data;
|
||||
struct qb_ipc_request_header *hdr;
|
||||
struct my_req *req_pt;
|
||||
struct qb_ipc_response_header response;
|
||||
ssize_t res;
|
||||
struct iovec iov[2];
|
||||
char resp[100];
|
||||
int32_t sl;
|
||||
int32_t send_ten_events = QB_FALSE;
|
||||
|
||||
qb_log(LOG_DEBUG, "msg received (id:%d, size:%d)",
|
||||
req_pt->id, req_pt->size);
|
||||
hdr = (struct qb_ipc_request_header *)data;
|
||||
if (hdr->id == (QB_IPC_MSG_USER_START + 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
req_pt = (struct my_req *)data;
|
||||
qb_log(LOG_DEBUG, "msg received (id:%d, size:%d, data:%s)",
|
||||
req_pt->hdr.id, req_pt->hdr.size, req_pt->message);
|
||||
|
||||
if (strcmp(req_pt->message, "kill") == 0) {
|
||||
exit(0);
|
||||
}
|
||||
response.size = sizeof(struct qb_ipc_response_header);
|
||||
response.id = 13;
|
||||
response.error = 0;
|
||||
|
||||
snprintf(resp, 100, "ACK %zd bytes", size);
|
||||
sl = snprintf(resp, 100, "ACK %zd bytes", size) + 1;
|
||||
iov[0].iov_len = sizeof(response);
|
||||
iov[0].iov_base = &response;
|
||||
iov[1].iov_len = strlen(resp) + 1;
|
||||
iov[1].iov_len = sl;
|
||||
iov[1].iov_base = resp;
|
||||
response.size += sl;
|
||||
|
||||
res = qb_ipcs_response_sendv(c, iov, 2);
|
||||
send_ten_events = (strcmp(req_pt->message, "events") == 0);
|
||||
|
||||
if (use_events && !send_ten_events) {
|
||||
res = qb_ipcs_event_sendv(c, iov, 2);
|
||||
} else {
|
||||
res = qb_ipcs_response_sendv(c, iov, 2);
|
||||
}
|
||||
if (res < 0) {
|
||||
errno = - res;
|
||||
qb_perror(LOG_ERR, "qb_ipcs_response_send");
|
||||
}
|
||||
if (send_ten_events) {
|
||||
int32_t i;
|
||||
qb_log(LOG_INFO, "request to send 10 events");
|
||||
for (i = 0; i < 10; i++) {
|
||||
res = qb_ipcs_event_sendv(c, iov, 2);
|
||||
qb_log(LOG_INFO, "sent event %d res:%d", i, res);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
sigusr1_handler(int32_t num)
|
||||
{
|
||||
qb_log(LOG_DEBUG, "(%d)", num);
|
||||
@ -129,7 +162,7 @@ sigusr1_handler(int32_t num)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
show_usage(const char *name)
|
||||
{
|
||||
printf("usage: \n");
|
||||
@ -139,10 +172,9 @@ show_usage(const char *name)
|
||||
printf("\n");
|
||||
printf(" -h show this help text\n");
|
||||
printf(" -m use shared memory\n");
|
||||
printf(" -p use posix message queues\n");
|
||||
printf(" -s use sysv message queues\n");
|
||||
printf(" -u use unix sockets\n");
|
||||
printf(" -g use glib mainloop\n");
|
||||
printf(" -e use events\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@ -151,13 +183,13 @@ struct gio_to_qb_poll {
|
||||
gboolean is_used;
|
||||
GIOChannel *channel;
|
||||
int32_t events;
|
||||
void * data;
|
||||
void *data;
|
||||
qb_ipcs_dispatch_fn_t fn;
|
||||
enum qb_loop_priority p;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data)
|
||||
gio_read_socket(GIOChannel * gio, GIOCondition condition, gpointer data)
|
||||
{
|
||||
struct gio_to_qb_poll *adaptor = (struct gio_to_qb_poll *)data;
|
||||
gint fd = g_io_channel_unix_get_fd(gio);
|
||||
@ -165,15 +197,15 @@ gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data)
|
||||
return (adaptor->fn(fd, condition, adaptor->data) == 0);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
static int32_t
|
||||
my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
{
|
||||
struct gio_to_qb_poll *adaptor;
|
||||
GIOChannel *channel;
|
||||
int32_t res = 0;
|
||||
|
||||
res = qb_array_index(gio_map, fd, (void**)&adaptor);
|
||||
res = qb_array_index(gio_map, fd, (void **)&adaptor);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
@ -199,7 +231,7 @@ my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
|
||||
|
||||
static int32_t
|
||||
my_g_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t evts,
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -208,7 +240,7 @@ static int32_t
|
||||
my_g_dispatch_del(int32_t fd)
|
||||
{
|
||||
struct gio_to_qb_poll *adaptor;
|
||||
if (qb_array_index(gio_map, fd, (void**)&adaptor) == 0) {
|
||||
if (qb_array_index(gio_map, fd, (void **)&adaptor) == 0) {
|
||||
g_io_channel_unref(adaptor->channel);
|
||||
adaptor->is_used = FALSE;
|
||||
}
|
||||
@ -216,7 +248,7 @@ my_g_dispatch_del(int32_t fd)
|
||||
}
|
||||
#endif /* HAVE_GLIB */
|
||||
|
||||
static int32_t
|
||||
static int32_t
|
||||
my_job_add(enum qb_loop_priority p, void *data, qb_loop_job_dispatch_fn fn)
|
||||
{
|
||||
return qb_loop_job_add(bms_loop, p, data, fn);
|
||||
@ -224,14 +256,14 @@ my_job_add(enum qb_loop_priority p, void *data, qb_loop_job_dispatch_fn fn)
|
||||
|
||||
static int32_t
|
||||
my_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
{
|
||||
return qb_loop_poll_add(bms_loop, p, fd, evts, data, fn);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
static int32_t
|
||||
my_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t evts,
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
void *data, qb_ipcs_dispatch_fn_t fn)
|
||||
{
|
||||
return qb_loop_poll_mod(bms_loop, p, fd, evts, data, fn);
|
||||
}
|
||||
@ -245,9 +277,9 @@ my_dispatch_del(int32_t fd)
|
||||
int32_t
|
||||
main(int32_t argc, char *argv[])
|
||||
{
|
||||
const char *options = "mpsugh";
|
||||
const char *options = "mpseugh";
|
||||
int32_t opt;
|
||||
enum qb_ipc_type ipc_type = QB_IPC_SHM;
|
||||
enum qb_ipc_type ipc_type = QB_IPC_NATIVE;
|
||||
struct qb_ipcs_service_handlers sh = {
|
||||
.connection_accept = s1_connection_accept_fn,
|
||||
.connection_created = s1_connection_created_fn,
|
||||
@ -275,18 +307,15 @@ main(int32_t argc, char *argv[])
|
||||
case 'm':
|
||||
ipc_type = QB_IPC_SHM;
|
||||
break;
|
||||
case 's':
|
||||
ipc_type = QB_IPC_SYSV_MQ;
|
||||
break;
|
||||
case 'u':
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
break;
|
||||
case 'p':
|
||||
ipc_type = QB_IPC_POSIX_MQ;
|
||||
break;
|
||||
case 'g':
|
||||
use_glib = QB_TRUE;
|
||||
break;
|
||||
case 'e':
|
||||
use_events = QB_TRUE;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
show_usage(argv[0]);
|
||||
@ -296,10 +325,9 @@ main(int32_t argc, char *argv[])
|
||||
}
|
||||
signal(SIGINT, sigusr1_handler);
|
||||
|
||||
qb_log_init("ipcserver", LOG_USER, LOG_WARNING);
|
||||
qb_log_init("ipcserver", LOG_USER, LOG_TRACE);
|
||||
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, __FILE__,
|
||||
LOG_DEBUG);
|
||||
QB_LOG_FILTER_FILE, "*", LOG_TRACE);
|
||||
qb_log_format_set(QB_LOG_STDERR, "%f:%l [%p] %b");
|
||||
qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
|
||||
@ -321,7 +349,8 @@ main(int32_t argc, char *argv[])
|
||||
qb_ipcs_run(s1);
|
||||
g_main_loop_run(glib_loop);
|
||||
#else
|
||||
qb_log(LOG_ERR, "You don't seem to have glib-devel installed.\n");
|
||||
qb_log(LOG_ERR,
|
||||
"You don't seem to have glib-devel installed.\n");
|
||||
#endif
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
#include <qb/qbmap.h>
|
||||
|
||||
static void
|
||||
notify_fn(uint32_t event, char* key, void* old_value, void* value, void* user_data)
|
||||
notify_fn(uint32_t event, char *key, void *old_value, void *value,
|
||||
void *user_data)
|
||||
{
|
||||
if (event == QB_MAP_NOTIFY_FREE) {
|
||||
fprintf(stderr, "Notify[FREE] %s [%d]\n",
|
||||
@ -44,13 +45,14 @@ notify_fn(uint32_t event, char* key, void* old_value, void* value, void* user_da
|
||||
fprintf(stderr, " value = [%d]\n", *(int *)value);
|
||||
}
|
||||
if (old_value != NULL) {
|
||||
fprintf(stderr, " old value = [%d]\n", *(int *)old_value);
|
||||
fprintf(stderr, " old value = [%d]\n",
|
||||
*(int *)old_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_cs_keys(qb_map_t *m)
|
||||
add_cs_keys(qb_map_t * m)
|
||||
{
|
||||
qb_map_put(m, "compatibility", strdup("none"));
|
||||
qb_map_put(m, "totem.version", strdup("2"));
|
||||
@ -197,7 +199,7 @@ main(void)
|
||||
|
||||
iter = qb_map_pref_iter_create(trie, "test.");
|
||||
while ((key = qb_map_iter_next(iter, &val)) != NULL) {
|
||||
fprintf(stderr,"Iter %s [%d]\n", key, *(int*)val);
|
||||
fprintf(stderr, "Iter %s [%d]\n", key, *(int *)val);
|
||||
qb_map_rm(trie, key);
|
||||
}
|
||||
qb_map_iter_free(iter);
|
||||
|
||||
@ -29,18 +29,19 @@
|
||||
#define MY_TAG_TWO (1 << 1)
|
||||
#define MY_TAG_THREE (1 << 2)
|
||||
|
||||
static int32_t _log_priority = LOG_WARNING;
|
||||
static uint8_t _log_priority = LOG_WARNING;
|
||||
|
||||
static void func_one(void)
|
||||
static void
|
||||
func_one(void)
|
||||
{
|
||||
FILE* fd;
|
||||
FILE *fd;
|
||||
|
||||
qb_enter();
|
||||
qb_logt(LOG_DEBUG, MY_TAG_TWO, "arf arf?");
|
||||
qb_logt(LOG_CRIT, MY_TAG_THREE, "arrrg!");
|
||||
qb_logt(134, MY_TAG_THREE, "big priority");
|
||||
qb_logt(LOG_ERR, MY_TAG_THREE, "oops, I did it again");
|
||||
qb_log(LOG_INFO, "are you aware ...");
|
||||
qb_logt(LOG_CRIT, MY_TAG_THREE, "arrrg!");
|
||||
qb_logt(134, MY_TAG_THREE, "big priority");
|
||||
qb_logt(LOG_ERR, MY_TAG_THREE, "oops, I did it again");
|
||||
qb_log(LOG_INFO, "are you aware ...");
|
||||
|
||||
fd = fopen("/nothing.txt", "r+");
|
||||
if (fd == NULL) {
|
||||
@ -51,17 +52,19 @@ static void func_one(void)
|
||||
qb_leave();
|
||||
}
|
||||
|
||||
static void func_two(void)
|
||||
static void
|
||||
func_two(void)
|
||||
{
|
||||
qb_enter();
|
||||
qb_logt(LOG_DEBUG, 0, "arf arf?");
|
||||
qb_logt(LOG_CRIT, MY_TAG_ONE, "arrrg!");
|
||||
qb_log(LOG_ERR, "oops, I did it again");
|
||||
qb_logt(LOG_INFO, MY_TAG_THREE, "are you aware ...");
|
||||
qb_logt(LOG_CRIT, MY_TAG_ONE, "arrrg!");
|
||||
qb_log(LOG_ERR, "oops, I did it again");
|
||||
qb_logt(LOG_INFO, MY_TAG_THREE, "are you aware ...");
|
||||
qb_leave();
|
||||
}
|
||||
|
||||
static void show_usage(const char *name)
|
||||
static void
|
||||
show_usage(const char *name)
|
||||
{
|
||||
printf("usage: \n");
|
||||
printf("%s <options>\n", name);
|
||||
@ -80,9 +83,10 @@ static void show_usage(const char *name)
|
||||
static int32_t do_blackbox = QB_FALSE;
|
||||
static int32_t do_threaded = QB_FALSE;
|
||||
|
||||
static void sigsegv_handler(int sig)
|
||||
static void
|
||||
sigsegv_handler(int sig)
|
||||
{
|
||||
(void)signal (SIGSEGV, SIG_DFL);
|
||||
(void)signal(SIGSEGV, SIG_DFL);
|
||||
qb_log_fini();
|
||||
if (do_blackbox) {
|
||||
qb_log_blackbox_write_to_file("simple-log.fdata");
|
||||
@ -90,7 +94,8 @@ static void sigsegv_handler(int sig)
|
||||
raise(SIGSEGV);
|
||||
}
|
||||
|
||||
static const char *my_tags_stringify(uint32_t tags)
|
||||
static const char *
|
||||
my_tags_stringify(uint32_t tags)
|
||||
{
|
||||
if (qb_bit_is_set(tags, QB_LOG_TAG_LIBQB_MSG_BIT)) {
|
||||
return "libqb";
|
||||
@ -107,9 +112,7 @@ static const char *my_tags_stringify(uint32_t tags)
|
||||
|
||||
static void
|
||||
trace_logger(int32_t t,
|
||||
struct qb_log_callsite *cs,
|
||||
time_t timestamp,
|
||||
const char *msg)
|
||||
struct qb_log_callsite *cs, time_t timestamp, const char *msg)
|
||||
{
|
||||
char output_buffer[QB_LOG_MAX_LEN];
|
||||
output_buffer[0] = '\0';
|
||||
@ -122,14 +125,15 @@ m_filter(struct qb_log_callsite *cs)
|
||||
{
|
||||
if ((cs->priority >= LOG_ALERT &&
|
||||
cs->priority <= _log_priority) &&
|
||||
strcmp(cs->filename, __FILE__) == 0) {
|
||||
strcmp(cs->filename, __FILE__) == 0) {
|
||||
qb_bit_set(cs->targets, QB_LOG_STDERR);
|
||||
} else {
|
||||
qb_bit_clear(cs->targets, QB_LOG_STDERR);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t main(int32_t argc, char *argv[])
|
||||
int32_t
|
||||
main(int32_t argc, char *argv[])
|
||||
{
|
||||
const char *options = "vhteobdf:";
|
||||
int32_t opt;
|
||||
@ -182,7 +186,6 @@ int32_t main(int32_t argc, char *argv[])
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, do_threaded);
|
||||
qb_log_tags_stringify_fn_set(my_tags_stringify);
|
||||
|
||||
|
||||
if (do_stderr) {
|
||||
qb_log_filter_fn_set(m_filter);
|
||||
qb_log_format_set(QB_LOG_STDERR, "[%p] %4g: %f:%l %b");
|
||||
@ -223,13 +226,25 @@ int32_t main(int32_t argc, char *argv[])
|
||||
qb_log(LOG_DEBUG, "hello");
|
||||
qb_log(LOG_INFO, "this is an info");
|
||||
qb_log(LOG_NOTICE, "hello - notice?");
|
||||
{
|
||||
char * str = NULL;
|
||||
qb_log(LOG_ERR,
|
||||
"%s-%d-%s-%u",
|
||||
NULL, 952, str, 56);
|
||||
}
|
||||
func_one();
|
||||
func_two();
|
||||
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
if (!do_threaded) {
|
||||
/* Disabling syslog here will prevent the logs from
|
||||
* getting flushed in qb_log_fini() if threaded
|
||||
* logging is on.
|
||||
*/
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
|
||||
qb_log(LOG_WARNING, "no syslog");
|
||||
qb_log(LOG_ERR, "no syslog");
|
||||
qb_log(LOG_WARNING, "no syslog");
|
||||
qb_log(LOG_ERR, "no syslog");
|
||||
}
|
||||
|
||||
#if 0
|
||||
// test blackbox
|
||||
@ -240,8 +255,8 @@ int32_t main(int32_t argc, char *argv[])
|
||||
qb_log_blackbox_write_to_file("simple-log.fdata");
|
||||
qb_log_blackbox_print_from_file("simple-log.fdata");
|
||||
qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
unlink("simple-log.fdata");
|
||||
}
|
||||
qb_log_fini();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -19,8 +19,19 @@
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "os_base.h"
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif /* HAVE_NETINET_IN_H */
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif /* HAVE_ARPA_INET_H */
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif /* HAVE_NETDB_H */
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif /* HAVE_SYS_SOCKET_H */
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
@ -40,8 +51,9 @@ main(int argc, char *argv[])
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(5000);
|
||||
memcpy(&server_addr.sin_addr, host->h_addr_list[0], sizeof(server_addr.sin_addr));
|
||||
bzero(&(server_addr.sin_zero),8);
|
||||
memcpy(&server_addr.sin_addr, host->h_addr_list[0],
|
||||
sizeof(server_addr.sin_addr));
|
||||
bzero(&(server_addr.sin_zero), 8);
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&server_addr,
|
||||
sizeof(struct sockaddr)) == -1) {
|
||||
@ -49,7 +61,7 @@ main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
while (1) {
|
||||
printf("\nSEND (q or Q to quit) : ");
|
||||
if (fgets(send_data, 1024, stdin) == NULL) {
|
||||
continue;
|
||||
|
||||
@ -20,9 +20,21 @@
|
||||
*/
|
||||
#include "os_base.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif /* HAVE_NETINET_IN_H */
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#endif /* HAVE_ARPA_INET_H */
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif /* HAVE_NETDB_H */
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif /* HAVE_SYS_SOCKET_H */
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif /* HAVE_SYS_POLL_H */
|
||||
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qbloop.h>
|
||||
@ -47,8 +59,7 @@ sock_read_fn(int32_t fd, int32_t revents, void *data)
|
||||
}
|
||||
recv_data[bytes_recieved] = '\0';
|
||||
|
||||
if (strcmp(recv_data, "q") == 0 ||
|
||||
strcmp(recv_data, "Q") == 0) {
|
||||
if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0) {
|
||||
printf("Quiting connection from socket %d\n", fd);
|
||||
close(fd);
|
||||
return QB_FALSE;
|
||||
@ -64,7 +75,7 @@ static int32_t
|
||||
sock_accept_fn(int32_t fd, int32_t revents, void *data)
|
||||
{
|
||||
struct sockaddr_in client_addr;
|
||||
qb_loop_t * ml = (qb_loop_t*)data;
|
||||
qb_loop_t *ml = (qb_loop_t *) data;
|
||||
socklen_t sin_size = sizeof(struct sockaddr_in);
|
||||
int connected = accept(fd, (struct sockaddr *)&client_addr, &sin_size);
|
||||
|
||||
@ -73,12 +84,9 @@ sock_accept_fn(int32_t fd, int32_t revents, void *data)
|
||||
return QB_TRUE;
|
||||
}
|
||||
printf("I got a connection from (%s , %d)\n",
|
||||
inet_ntoa(client_addr.sin_addr),
|
||||
ntohs(client_addr.sin_port));
|
||||
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
|
||||
|
||||
qb_loop_poll_add(ml, QB_LOOP_MED,
|
||||
connected, POLLIN,
|
||||
ml, sock_read_fn);
|
||||
qb_loop_poll_add(ml, QB_LOOP_MED, connected, POLLIN, ml, sock_read_fn);
|
||||
|
||||
return QB_TRUE;
|
||||
}
|
||||
@ -86,7 +94,7 @@ sock_accept_fn(int32_t fd, int32_t revents, void *data)
|
||||
static int32_t
|
||||
please_exit_fn(int32_t rsignal, void *data)
|
||||
{
|
||||
qb_loop_t * ml = (qb_loop_t*)data;
|
||||
qb_loop_t *ml = (qb_loop_t *) data;
|
||||
|
||||
printf("Shutting down at you request...\n");
|
||||
qb_loop_stop(ml);
|
||||
@ -99,20 +107,16 @@ main(int argc, char *argv[])
|
||||
int sock;
|
||||
int true_opt = 1;
|
||||
struct sockaddr_in server_addr;
|
||||
qb_loop_t * ml = qb_loop_create();
|
||||
qb_loop_t *ml = qb_loop_create();
|
||||
|
||||
if ((sock = socket(AF_INET,
|
||||
SOCK_STREAM,
|
||||
0)) == -1) {
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
||||
perror("Socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setsockopt(sock,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
&true_opt,
|
||||
sizeof(int)) == -1) {
|
||||
SO_REUSEADDR, &true_opt, sizeof(int)) == -1) {
|
||||
perror("Setsockopt");
|
||||
exit(1);
|
||||
}
|
||||
@ -120,7 +124,7 @@ main(int argc, char *argv[])
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(5000);
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
bzero(&(server_addr.sin_zero),8);
|
||||
bzero(&(server_addr.sin_zero), 8);
|
||||
|
||||
printf("TCPServer binding to port 5000\n");
|
||||
if (bind(sock,
|
||||
@ -137,14 +141,9 @@ main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
qb_loop_poll_add(ml, QB_LOOP_MED,
|
||||
sock, POLLIN,
|
||||
ml, sock_accept_fn);
|
||||
qb_loop_poll_add(ml, QB_LOOP_MED, sock, POLLIN, ml, sock_accept_fn);
|
||||
|
||||
qb_loop_signal_add(ml, QB_LOOP_HIGH,
|
||||
SIGINT,
|
||||
ml, please_exit_fn,
|
||||
NULL);
|
||||
qb_loop_signal_add(ml, QB_LOOP_HIGH, SIGINT, ml, please_exit_fn, NULL);
|
||||
qb_loop_run(ml);
|
||||
|
||||
close(sock);
|
||||
|
||||
@ -164,7 +164,6 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_RT = @LIB_RT@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
|
||||
@ -6,6 +6,9 @@
|
||||
/* Compiling Debugging code */
|
||||
#undef DEBUG
|
||||
|
||||
/* Disable shared mem ipc */
|
||||
#undef DISABLE_IPC_SHM
|
||||
|
||||
/* Disable _POSIX_THREAD_PROCESS_SHARED */
|
||||
#undef DISABLE_POSIX_THREAD_PROCESS_SHARED
|
||||
|
||||
@ -21,6 +24,10 @@
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#undef HAVE_CLOCK_GETTIME
|
||||
|
||||
/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_STRERROR_R
|
||||
|
||||
/* "Have /usr/share/dict/words" */
|
||||
#undef HAVE_DICT_WORDS
|
||||
|
||||
@ -51,6 +58,12 @@
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#undef HAVE_GETPAGESIZE
|
||||
|
||||
/* Define to 1 if you have the `getpeereid' function. */
|
||||
#undef HAVE_GETPEEREID
|
||||
|
||||
/* Define to 1 if you have the `getpeerucred' function. */
|
||||
#undef HAVE_GETPEERUCRED
|
||||
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
#undef HAVE_GETRLIMIT
|
||||
|
||||
@ -63,17 +76,8 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||
#undef HAVE_LIBPTHREAD
|
||||
|
||||
/* Define to 1 if you have the `rt' library (-lrt). */
|
||||
#undef HAVE_LIBRT
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#undef HAVE_KQUEUE
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
@ -96,20 +100,23 @@
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the <mqueue.h> header file. */
|
||||
#undef HAVE_MQUEUE_H
|
||||
|
||||
/* Define to 1 if you have the `munmap' function. */
|
||||
#undef HAVE_MUNMAP
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#undef HAVE_NETDB_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* have posix message queues */
|
||||
#undef HAVE_POSIX_MQ
|
||||
/* Define to 1 if you have the `pthread_condattr_setpshared' function. */
|
||||
#undef HAVE_PTHREAD_CONDATTR_SETPSHARED
|
||||
|
||||
/* Define to 1 if you have the `pthread_mutexattr_setpshared' function. */
|
||||
#undef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
|
||||
|
||||
/* Define to 1 if you have the `pthread_setschedparam' function. */
|
||||
#undef HAVE_PTHREAD_SETSCHEDPARAM
|
||||
@ -129,18 +136,33 @@
|
||||
/* Define to 1 if you have the `sched_setscheduler' function. */
|
||||
#undef HAVE_SCHED_SETSCHEDULER
|
||||
|
||||
/* Define to 1 if you have the `semtimedop' function. */
|
||||
#undef HAVE_SEMTIMEDOP
|
||||
|
||||
/* Define to 1 if you have union semun. */
|
||||
#undef HAVE_SEMUN
|
||||
|
||||
/* Define to 1 if you have the `sem_timedwait' function. */
|
||||
#undef HAVE_SEM_TIMEDWAIT
|
||||
|
||||
/* have slow tests */
|
||||
#undef HAVE_SLOW_TESTS
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#undef HAVE_SOCKET
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
@ -150,8 +172,8 @@
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#undef HAVE_STRERROR_R
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
@ -171,18 +193,21 @@
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#undef HAVE_STRSTR
|
||||
|
||||
/* Define to 1 if struct sockaddr_un has a member sun_len */
|
||||
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#undef HAVE_SYSCONF
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
/* have sysv message queues */
|
||||
#undef HAVE_SYSV_MQ
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
#undef HAVE_SYS_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
@ -253,12 +278,6 @@
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Shared memory define for Darwin platform */
|
||||
#undef MAP_ANONYMOUS
|
||||
|
||||
/* Number of chars in a file name */
|
||||
#undef NAME_MAX
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
@ -286,9 +305,6 @@
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Number of chars in a path name including nul */
|
||||
#undef PATH_MAX
|
||||
|
||||
/* alpha */
|
||||
#undef QB_ARCH_ALPHA
|
||||
|
||||
@ -313,6 +329,9 @@
|
||||
/* Compiling for BSD platform */
|
||||
#undef QB_BSD
|
||||
|
||||
/* Compiling for Cygwin platform */
|
||||
#undef QB_CYGWIN
|
||||
|
||||
/* Compiling for Darwin platform */
|
||||
#undef QB_DARWIN
|
||||
|
||||
@ -337,14 +356,46 @@
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Prevent being scheduled RR */
|
||||
#undef TS_CLASS
|
||||
/* Define to 1 if strerror_r returns char *. */
|
||||
#undef STRERROR_R_CHAR_P
|
||||
|
||||
/* Unix path length */
|
||||
#undef UNIX_PATH_MAX
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* The semun structure is undefined */
|
||||
#undef _SEM_SEMUN_UNDEFINED
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
@ -397,6 +448,10 @@
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 16 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint16_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint32_t
|
||||
|
||||
@ -25,10 +25,6 @@
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif /* _GNU_SOURCE */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
@ -45,6 +41,10 @@
|
||||
#include <stdint.h>
|
||||
#endif /* HAVE_STDINT_H */
|
||||
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif /* HAVE_STDDEF_H */
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
@ -107,24 +107,55 @@
|
||||
#define HAVE_EPOLL 1
|
||||
#endif /* HAVE_EPOLL_CREATE */
|
||||
|
||||
/*
|
||||
* Darwin claims to support process shared synchronization
|
||||
* but it really does not. The unistd.h header file is wrong.
|
||||
#if defined(__UCLIBC__)
|
||||
#define DISABLE_POSIX_THREAD_PROCESS_SHARED 1
|
||||
#endif
|
||||
|
||||
/* The pshared semaphore madness:
|
||||
* To have a usable pshared semaphore we need the timed_wait api
|
||||
* and pshared functionality.
|
||||
*
|
||||
* The order of choice is:
|
||||
* 1) real posix sem -> HAVE_POSIX_PSHARED_SEMAPHORE
|
||||
* 2) sysv sems (if we have semtimedop) -> HAVE_SYSV_PSHARED_SEMAPHORE
|
||||
* 3) faked sems using pthread_cond_timedwait -> HAVE_RPL_PSHARED_SEMAPHORE
|
||||
* 4) ENOTSUP
|
||||
*/
|
||||
#if defined(DISABLE_POSIX_THREAD_PROCESS_SHARED) || defined(__UCLIBC__)
|
||||
#undef HAVE_POSIX_SHARED_SEMAPHORE
|
||||
#undef HAVE_PTHREAD_SHARED_SPIN_LOCK
|
||||
#else
|
||||
#if _POSIX_THREAD_PROCESS_SHARED > 0
|
||||
#define HAVE_POSIX_SHARED_SEMAPHORE 1
|
||||
#undef HAVE_POSIX_PSHARED_SEMAPHORE
|
||||
#undef HAVE_SYSV_PSHARED_SEMAPHORE
|
||||
#undef HAVE_RPL_PSHARED_SEMAPHORE
|
||||
|
||||
#if defined(HAVE_PTHREAD_SPIN_LOCK)
|
||||
#define HAVE_PTHREAD_SHARED_SPIN_LOCK 1
|
||||
#endif /* HAVE_PTHREAD_SPIN_LOCK */
|
||||
|
||||
#endif /* _POSIX_THREAD_PROCESS_SHARED */
|
||||
#if defined(DISABLE_POSIX_THREAD_PROCESS_SHARED)
|
||||
#undef HAVE_PTHREAD_SHARED_SPIN_LOCK
|
||||
#endif /* DISABLE_POSIX_THREAD_PROCESS_SHARED */
|
||||
|
||||
#if !defined(DISABLE_POSIX_THREAD_PROCESS_SHARED) && \
|
||||
_POSIX_THREAD_PROCESS_SHARED > 0
|
||||
|
||||
#if defined(HAVE_PTHREAD_SPIN_LOCK)
|
||||
#define HAVE_PTHREAD_SHARED_SPIN_LOCK 1
|
||||
#endif /* HAVE_PTHREAD_SPIN_LOCK */
|
||||
|
||||
#if defined(HAVE_SEM_TIMEDWAIT)
|
||||
#define HAVE_POSIX_PSHARED_SEMAPHORE 1
|
||||
#else
|
||||
#if defined(HAVE_PTHREAD_CONDATTR_SETPSHARED) && \
|
||||
defined(HAVE_PTHREAD_MUTEXATTR_SETPSHARED)
|
||||
#define HAVE_RPL_PSHARED_SEMAPHORE 1
|
||||
#endif
|
||||
#endif /* HAVE_SEM_TIMEDWAIT */
|
||||
#endif /* posix pshared */
|
||||
|
||||
#ifdef HAVE_SEMTIMEDOP
|
||||
#define HAVE_SYSV_PSHARED_SEMAPHORE 1
|
||||
#endif /* HAVE_SEM_TIMEDWAIT */
|
||||
|
||||
#if !defined(HAVE_SYSV_PSHARED_SEMAPHORE) && \
|
||||
!defined(HAVE_POSIX_PSHARED_SEMAPHORE) && \
|
||||
!defined(HAVE_RPL_PSHARED_SEMAPHORE)
|
||||
#define DISABLE_IPC_SHM 1
|
||||
#endif /* HAVE PSHARED SEMAPHORE */
|
||||
|
||||
#ifndef HAVE_STRCHRNUL
|
||||
char *strchrnul (const char *s, int c_in);
|
||||
#endif
|
||||
@ -137,4 +168,11 @@ size_t strlcpy(char *dest, const char *src, size_t maxlen);
|
||||
size_t strlcat(char *dest, const char *src, size_t maxlen);
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
#ifndef NAME_MAX
|
||||
#define NAME_MAX 255
|
||||
#endif
|
||||
|
||||
#endif /* QB_OS_BASE_H_DEFINED */
|
||||
|
||||
@ -154,7 +154,6 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_RT = @LIB_RT@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
|
||||
@ -47,6 +47,7 @@ enum qb_ipc_type {
|
||||
QB_IPC_SHM,
|
||||
QB_IPC_POSIX_MQ,
|
||||
QB_IPC_SYSV_MQ,
|
||||
QB_IPC_NATIVE,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -106,6 +106,10 @@ int32_t qb_ipcc_fc_enable_max_set(qb_ipcc_connection_t * c, uint32_t max);
|
||||
* @param msg_ptr pointer to a message to send
|
||||
* @param msg_len the size of the message
|
||||
* @return (size sent, -errno == error)
|
||||
*
|
||||
* @note the msg_ptr must include a qb_ipc_request_header at
|
||||
* the top of the message. The server will read the size field
|
||||
* to determine how much to recv.
|
||||
*/
|
||||
ssize_t qb_ipcc_send(qb_ipcc_connection_t* c, const void *msg_ptr,
|
||||
size_t msg_len);
|
||||
@ -116,6 +120,9 @@ ssize_t qb_ipcc_send(qb_ipcc_connection_t* c, const void *msg_ptr,
|
||||
* @param iov pointer to an iovec struct to send
|
||||
* @param iov_len the number of iovecs used
|
||||
* @return (size sent, -errno == error)
|
||||
*
|
||||
* @note the iov[0] must be a qb_ipc_request_header. The server will
|
||||
* read the size field to determine how much to recv.
|
||||
*/
|
||||
ssize_t qb_ipcc_sendv(qb_ipcc_connection_t* c, const struct iovec* iov,
|
||||
size_t iov_len);
|
||||
@ -127,6 +134,9 @@ ssize_t qb_ipcc_sendv(qb_ipcc_connection_t* c, const struct iovec* iov,
|
||||
* @param msg_len the size of the buffer
|
||||
* @param ms_timeout max time to wait for a response
|
||||
* @return (size recv'ed, -errno == error)
|
||||
*
|
||||
* @note that msg_ptr will include a qb_ipc_response_header at
|
||||
* the top of the message.
|
||||
*/
|
||||
ssize_t qb_ipcc_recv(qb_ipcc_connection_t* c, void *msg_ptr,
|
||||
size_t msg_len, int32_t ms_timeout);
|
||||
@ -141,6 +151,12 @@ ssize_t qb_ipcc_recv(qb_ipcc_connection_t* c, void *msg_ptr,
|
||||
* @param msg_len the size of the buffer
|
||||
* @param ms_timeout max time to wait for a response
|
||||
*
|
||||
* @note the iov[0] must include a qb_ipc_request_header at
|
||||
* the top of the message. The server will read the size field
|
||||
* to determine how much to recv.
|
||||
* @note that msg_ptr will include a qb_ipc_response_header at
|
||||
* the top of the message.
|
||||
*
|
||||
* @see qb_ipcc_sendv() qb_ipcc_recv()
|
||||
*/
|
||||
ssize_t qb_ipcc_sendv_recv(qb_ipcc_connection_t *c,
|
||||
@ -158,6 +174,9 @@ ssize_t qb_ipcc_sendv_recv(qb_ipcc_connection_t *c,
|
||||
* 0 == no wait, negative == block, positive == wait X ms.
|
||||
* @param ms_timeout max time to wait for a response
|
||||
* @return size of the message or error (-errno)
|
||||
*
|
||||
* @note that msg_ptr will include a qb_ipc_response_header at
|
||||
* the top of the message.
|
||||
*/
|
||||
ssize_t qb_ipcc_event_recv(qb_ipcc_connection_t* c, void *msg_ptr,
|
||||
size_t msg_len, int32_t ms_timeout);
|
||||
@ -180,6 +199,14 @@ void qb_ipcc_context_set(qb_ipcc_connection_t *c, void *context);
|
||||
*/
|
||||
void *qb_ipcc_context_get(qb_ipcc_connection_t *c);
|
||||
|
||||
/**
|
||||
* Is the connection connected?
|
||||
*
|
||||
* @param c connection instance
|
||||
* @retval QB_TRUE when connected
|
||||
* @retval QB_FALSE when not connected
|
||||
*/
|
||||
int32_t qb_ipcc_is_connected(qb_ipcc_connection_t *c);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -73,6 +73,18 @@ struct qb_ipcs_connection_stats {
|
||||
uint64_t flow_control_count;
|
||||
};
|
||||
|
||||
struct qb_ipcs_connection_stats_2 {
|
||||
int32_t client_pid;
|
||||
uint64_t requests;
|
||||
uint64_t responses;
|
||||
uint64_t events;
|
||||
uint64_t send_retries;
|
||||
uint64_t recv_retries;
|
||||
int32_t flow_control_state;
|
||||
uint64_t flow_control_count;
|
||||
uint32_t event_q_length;
|
||||
};
|
||||
|
||||
typedef int32_t (*qb_ipcs_dispatch_fn_t) (int32_t fd, int32_t revents,
|
||||
void *data);
|
||||
|
||||
@ -105,8 +117,11 @@ struct qb_ipcs_poll_handlers {
|
||||
* The type of checks you should do are authentication, service availabilty
|
||||
* or process resource constraints.
|
||||
* @return 0 to accept or -errno to indicate a failure (sent back to the client)
|
||||
*
|
||||
* @note you can call qb_ipcs_connection_auth_set() within this function.
|
||||
*/
|
||||
typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
|
||||
typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c,
|
||||
uid_t uid, gid_t gid);
|
||||
|
||||
/**
|
||||
* This is called after a new connection has been created.
|
||||
@ -198,7 +213,8 @@ void qb_ipcs_destroy(qb_ipcs_service_t* s);
|
||||
* @param s service instance
|
||||
* @param rl the new rate
|
||||
*/
|
||||
void qb_ipcs_request_rate_limit(qb_ipcs_service_t* s, enum qb_ipcs_rate_limit rl);
|
||||
void qb_ipcs_request_rate_limit(qb_ipcs_service_t* s,
|
||||
enum qb_ipcs_rate_limit rl);
|
||||
|
||||
/**
|
||||
* Send a response to a incomming request.
|
||||
@ -207,8 +223,13 @@ void qb_ipcs_request_rate_limit(qb_ipcs_service_t* s, enum qb_ipcs_rate_limit rl
|
||||
* @param data the message to send
|
||||
* @param size the size of the message
|
||||
* @return size sent or -errno for errors
|
||||
*
|
||||
* @note the data must include a qb_ipc_response_header at
|
||||
* the top of the message. The client will read the size field
|
||||
* to determine how much to recv.
|
||||
*/
|
||||
ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, const void *data, size_t size);
|
||||
ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, const void *data,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* Send a response to a incomming request.
|
||||
@ -217,8 +238,12 @@ ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, const void *data, size_t
|
||||
* @param iov the iovec struct that points to the message to send
|
||||
* @param iov_len the number of iovecs.
|
||||
* @return size sent or -errno for errors
|
||||
*
|
||||
* @note the iov[0] must be a qb_ipc_response_header. The client will
|
||||
* read the size field to determine how much to recv.
|
||||
*/
|
||||
ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c, const struct iovec * iov, size_t iov_len);
|
||||
ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c,
|
||||
const struct iovec * iov, size_t iov_len);
|
||||
|
||||
/**
|
||||
* Send an asyncronous event message to the client.
|
||||
@ -227,8 +252,13 @@ ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c, const struct iovec * iov
|
||||
* @param data the message to send
|
||||
* @param size the size of the message
|
||||
* @return size sent or -errno for errors
|
||||
*
|
||||
* @note the data must include a qb_ipc_response_header at
|
||||
* the top of the message. The client will read the size field
|
||||
* to determine how much to recv.
|
||||
*/
|
||||
ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data, size_t size);
|
||||
ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* Send an asyncronous event message to the client.
|
||||
@ -237,8 +267,12 @@ ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data, size_t siz
|
||||
* @param iov the iovec struct that points to the message to send
|
||||
* @param iov_len the number of iovecs.
|
||||
* @return size sent or -errno for errors
|
||||
*
|
||||
* @note the iov[0] must be a qb_ipc_response_header. The client will
|
||||
* read the size field to determine how much to recv.
|
||||
*/
|
||||
ssize_t qb_ipcs_event_sendv(qb_ipcs_connection_t *c, const struct iovec * iov, size_t iov_len);
|
||||
ssize_t qb_ipcs_event_sendv(qb_ipcs_connection_t *c, const struct iovec * iov,
|
||||
size_t iov_len);
|
||||
|
||||
/**
|
||||
* Increment the connection's reference counter.
|
||||
@ -290,6 +324,7 @@ void *qb_ipcs_context_get(qb_ipcs_connection_t *c);
|
||||
/**
|
||||
* Get the connection statistics.
|
||||
*
|
||||
* @deprecated from v0.13.0 onwards, use qb_ipcs_connection_stats_get_2
|
||||
* @param stats (out) the statistics structure
|
||||
* @param clear_after_read clear stats after copying them into stats
|
||||
* @param c connection instance
|
||||
@ -298,6 +333,17 @@ void *qb_ipcs_context_get(qb_ipcs_connection_t *c);
|
||||
int32_t qb_ipcs_connection_stats_get(qb_ipcs_connection_t *c,
|
||||
struct qb_ipcs_connection_stats* stats,
|
||||
int32_t clear_after_read);
|
||||
/**
|
||||
* Get (and allocate) the connection statistics.
|
||||
*
|
||||
* @param clear_after_read clear stats after copying them into stats
|
||||
* @param c connection instance
|
||||
* @retval NULL if no memory or invalid connection
|
||||
* @retval allocated statistics structure (user must free it).
|
||||
*/
|
||||
struct qb_ipcs_connection_stats_2*
|
||||
qb_ipcs_connection_stats_get_2(qb_ipcs_connection_t *c,
|
||||
int32_t clear_after_read);
|
||||
|
||||
/**
|
||||
* Get the service statistics.
|
||||
@ -333,6 +379,23 @@ qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_t* pt);
|
||||
qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_t* pt,
|
||||
qb_ipcs_connection_t *current);
|
||||
|
||||
/**
|
||||
* Set the permissions on and shared memory files so that both processes can
|
||||
* read and write to them.
|
||||
*
|
||||
* @param conn connection instance
|
||||
* @param uid the user id to set.
|
||||
* @param gid the group id to set.
|
||||
* @param mode the mode to set.
|
||||
*
|
||||
* @see chmod() chown()
|
||||
* @note this must be called within the qb_ipcs_connection_accept_fn()
|
||||
* callback.
|
||||
*/
|
||||
void qb_ipcs_connection_auth_set(qb_ipcs_connection_t *conn, uid_t uid,
|
||||
gid_t gid, mode_t mode);
|
||||
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -98,6 +98,12 @@ extern "C" {
|
||||
* LOG_INFO - LOG_DEBUG);
|
||||
* @endcode
|
||||
*
|
||||
* To ensure all logs to file targets are fsync'ed (default QB_FALSE)
|
||||
* @code
|
||||
* qb_log_ctl(mytarget, QB_LOG_CONF_FILE_SYNC, QB_TRUE);
|
||||
* @endcode
|
||||
*
|
||||
*
|
||||
* @par Filtering messages.
|
||||
* To have more power over what log messages go to which target you can apply
|
||||
* filters to the targets. What happens is the desired callsites have the
|
||||
@ -393,6 +399,7 @@ enum qb_log_conf {
|
||||
QB_LOG_CONF_THREADED,
|
||||
QB_LOG_CONF_PRIORITY_BUMP,
|
||||
QB_LOG_CONF_STATE_GET,
|
||||
QB_LOG_CONF_FILE_SYNC,
|
||||
};
|
||||
|
||||
enum qb_log_filter_type {
|
||||
|
||||
@ -239,7 +239,7 @@ int32_t qb_loop_poll_del(qb_loop_t *l, int32_t fd);
|
||||
*
|
||||
* @param l pointer to the loop instance
|
||||
* @param p the priority
|
||||
* @param signal (SIGHUP or SIGINT) etc ....
|
||||
* @param sig (SIGHUP or SIGINT) etc ....
|
||||
* @param data user data passed into the dispatch function
|
||||
* @param dispatch_fn callback function
|
||||
* @param handle (out) a reference to the signal job
|
||||
@ -247,7 +247,7 @@ int32_t qb_loop_poll_del(qb_loop_t *l, int32_t fd);
|
||||
*/
|
||||
int32_t qb_loop_signal_add(qb_loop_t *l,
|
||||
enum qb_loop_priority p,
|
||||
int32_t signal,
|
||||
int32_t sig,
|
||||
void *data,
|
||||
qb_loop_signal_dispatch_fn dispatch_fn,
|
||||
qb_loop_signal_handle *handle);
|
||||
@ -257,7 +257,7 @@ int32_t qb_loop_signal_add(qb_loop_t *l,
|
||||
*
|
||||
* @param l pointer to the loop instance
|
||||
* @param p the priority
|
||||
* @param signal (SIGHUP or SIGINT) etc ....
|
||||
* @param sig (SIGHUP or SIGINT) etc ....
|
||||
* @param data user data passed into the dispatch function
|
||||
* @param dispatch_fn callback function
|
||||
* @param handle (in) a reference to the signal job
|
||||
@ -265,7 +265,7 @@ int32_t qb_loop_signal_add(qb_loop_t *l,
|
||||
*/
|
||||
int32_t qb_loop_signal_mod(qb_loop_t *l,
|
||||
enum qb_loop_priority p,
|
||||
int32_t signal,
|
||||
int32_t sig,
|
||||
void *data,
|
||||
qb_loop_signal_dispatch_fn dispatch_fn,
|
||||
qb_loop_signal_handle handle);
|
||||
|
||||
@ -99,6 +99,13 @@ extern "C" {
|
||||
*/
|
||||
#define QB_RB_FLAG_SHARED_PROCESS 0x08
|
||||
|
||||
/**
|
||||
* Don't use semaphores, only atomic ops.
|
||||
* This mean that the timeout passed into qb_rb_chunk_read()
|
||||
* will be ignored.
|
||||
*/
|
||||
#define QB_RB_FLAG_NO_SEMAPHORE 0x10
|
||||
|
||||
struct qb_ringbuffer_s;
|
||||
typedef struct qb_ringbuffer_s qb_ringbuffer_t;
|
||||
|
||||
@ -278,6 +285,14 @@ qb_ringbuffer_t *qb_rb_create_from_file(int32_t fd, uint32_t flags);
|
||||
*/
|
||||
int32_t qb_rb_chown(qb_ringbuffer_t * rb, uid_t owner, gid_t group);
|
||||
|
||||
/**
|
||||
* Like 'chmod' it changes the mode of the ringbuffers resources.
|
||||
* @param mode mode to change to
|
||||
* @param rb ringbuffer instance
|
||||
* @retval 0 == ok
|
||||
* @retval -errno for error
|
||||
*/
|
||||
int32_t qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -32,7 +32,7 @@ typedef void *timer_handle;
|
||||
#define TIMER_HANDLE
|
||||
#endif
|
||||
|
||||
static int64_t timerlist_hertz = HZ;
|
||||
static int64_t timerlist_hertz;
|
||||
|
||||
struct timerlist {
|
||||
struct qb_list_head timer_head;
|
||||
|
||||
@ -21,26 +21,49 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h log_int.h map_int.h
|
||||
noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h \
|
||||
log_int.h map_int.h rpl_sem.h loop_poll_int.h
|
||||
|
||||
#
|
||||
# Here are a set of rules to help you update your library version information:
|
||||
# Start with version information of ‘0:0:0’ for each libtool library.
|
||||
# Update the version information only immediately before a public release of your software.
|
||||
# More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster.
|
||||
# If the library source code has changed at all since the last update, then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
|
||||
# If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
|
||||
# If any interfaces have been added since the last public release, then increment age.
|
||||
# If any interfaces have been removed since the last public release, then set age to 0.
|
||||
#
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
|
||||
lib_LTLIBRARIES = libqb.la
|
||||
|
||||
libqb_la_LDFLAGS = -version-info 11:1:11
|
||||
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \
|
||||
loop.c loop_poll.c loop_job.c loop_timerlist.c \
|
||||
ipcc.c ipcs.c ipc_shm.c ipc_us.c \
|
||||
# From: http://sourceware.org/autobook/autobook/autobook_91.html
|
||||
# (for my own sanity).
|
||||
#
|
||||
# 1) If you have changed any of the sources for this library, the revision
|
||||
# number must be incremented. This is a new revision of the current
|
||||
# interface.
|
||||
#
|
||||
# 2) If the interface has changed, then current must be incremented, and
|
||||
# revision reset to `0'. This is the first revision of a new interface.
|
||||
#
|
||||
# 3) If the new interface is a superset of the previous interface
|
||||
# (that is, if the previous interface has not been broken by the changes
|
||||
# in this new release), then age must be incremented. This release is
|
||||
# backwards compatible with the previous release.
|
||||
#
|
||||
# 4) If the new interface has removed elements with respect to the previous
|
||||
# interface, then you have broken backward compatibility and age must be
|
||||
# reset to `0'. This release has a new, but backwards incompatible
|
||||
# interface. For example, if the next release of the library included
|
||||
# some new commands for an existing socket protocol, you would use
|
||||
# -version-info 1:0:1. This is the first revision of a new interface.
|
||||
# This release is backwards compatible with the previous release.
|
||||
# Later, you implement a faster way of handling part of the algorithm
|
||||
# at the core of the library, and release it with -version-info 1:1:1.
|
||||
# This is a new revision of the current interface.
|
||||
# Unfortunately the speed of your new implementation can only be fully
|
||||
# exploited by changing the API to access the structures at a lower level,
|
||||
# which breaks compatibility with the previous interface, so you release
|
||||
# it as -version-info 2:0:0. This release has a new, but backwards
|
||||
# incompatible interface.
|
||||
#
|
||||
libqb_la_LDFLAGS = -version-info 14:2:14
|
||||
|
||||
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
|
||||
array.c loop.c loop_poll.c loop_job.c \
|
||||
loop_timerlist.c ipcc.c ipcs.c ipc_shm.c ipc_us.c \
|
||||
log.c log_thread.c log_blackbox.c log_file.c \
|
||||
log_syslog.c log_dcs.c log_format.c \
|
||||
map.c skiplist.c hashtable.c trie.c
|
||||
@ -48,13 +71,21 @@ source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \
|
||||
libqb_la_SOURCES = $(source_to_lint) unix.c
|
||||
libqb_la_LIBADD = @LTLIBOBJS@
|
||||
|
||||
if HAVE_SYSV_MQ
|
||||
libqb_la_SOURCES+=ipc_sysv_mq.c
|
||||
if HAVE_SEM_TIMEDWAIT
|
||||
else
|
||||
libqb_la_SOURCES+=rpl_sem.c
|
||||
endif
|
||||
|
||||
if HAVE_POSIX_MQ
|
||||
libqb_la_SOURCES+=ipc_posix_mq.c
|
||||
if HAVE_EPOLL
|
||||
libqb_la_SOURCES+=loop_poll_epoll.c
|
||||
else
|
||||
if HAVE_KQUEUE
|
||||
libqb_la_SOURCES+=loop_poll_kqueue.c
|
||||
else
|
||||
libqb_la_SOURCES+=loop_poll_poll.c
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libqb.pc
|
||||
@ -62,8 +93,11 @@ pkgconfig_DATA = libqb.pc
|
||||
if HAVE_SPLINT
|
||||
check_SCRIPTS = run_splint.sh
|
||||
TESTS = $(check_SCRIPTS)
|
||||
# this is a hack because debian/ubuntu don't set the arch path
|
||||
# in splint.
|
||||
DEB_INCLUDES = -I/usr/include/x86_64-linux-gnu -I/usr/include/i386-linux-gnu
|
||||
|
||||
ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DEB_INCLUDES) \
|
||||
$(libqb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CPPFLAGS) \
|
||||
$(LINT_FLAGS)
|
||||
|
||||
|
||||
447
lib/Makefile.in
447
lib/Makefile.in
@ -56,8 +56,10 @@ PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@HAVE_SYSV_MQ_TRUE@am__append_1 = ipc_sysv_mq.c
|
||||
@HAVE_POSIX_MQ_TRUE@am__append_2 = ipc_posix_mq.c
|
||||
@HAVE_SEM_TIMEDWAIT_FALSE@am__append_1 = rpl_sem.c
|
||||
@HAVE_EPOLL_TRUE@am__append_2 = loop_poll_epoll.c
|
||||
@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_TRUE@am__append_3 = loop_poll_kqueue.c
|
||||
@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_FALSE@am__append_4 = loop_poll_poll.c
|
||||
subdir = lib
|
||||
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/libqb.pc.in strchrnul.c \
|
||||
@ -109,16 +111,21 @@ am__libqb_la_SOURCES_DIST = util.c hdb.c ringbuffer.c \
|
||||
loop_timerlist.c ipcc.c ipcs.c ipc_shm.c ipc_us.c log.c \
|
||||
log_thread.c log_blackbox.c log_file.c log_syslog.c log_dcs.c \
|
||||
log_format.c map.c skiplist.c hashtable.c trie.c unix.c \
|
||||
ipc_sysv_mq.c ipc_posix_mq.c
|
||||
rpl_sem.c loop_poll_epoll.c loop_poll_kqueue.c \
|
||||
loop_poll_poll.c
|
||||
am__objects_1 = util.lo hdb.lo ringbuffer.lo ringbuffer_helper.lo \
|
||||
array.lo loop.lo loop_poll.lo loop_job.lo loop_timerlist.lo \
|
||||
ipcc.lo ipcs.lo ipc_shm.lo ipc_us.lo log.lo log_thread.lo \
|
||||
log_blackbox.lo log_file.lo log_syslog.lo log_dcs.lo \
|
||||
log_format.lo map.lo skiplist.lo hashtable.lo trie.lo
|
||||
@HAVE_SYSV_MQ_TRUE@am__objects_2 = ipc_sysv_mq.lo
|
||||
@HAVE_POSIX_MQ_TRUE@am__objects_3 = ipc_posix_mq.lo
|
||||
@HAVE_SEM_TIMEDWAIT_FALSE@am__objects_2 = rpl_sem.lo
|
||||
@HAVE_EPOLL_TRUE@am__objects_3 = loop_poll_epoll.lo
|
||||
@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_TRUE@am__objects_4 = \
|
||||
@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_TRUE@ loop_poll_kqueue.lo
|
||||
@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_FALSE@am__objects_5 = \
|
||||
@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_FALSE@ loop_poll_poll.lo
|
||||
am_libqb_la_OBJECTS = $(am__objects_1) unix.lo $(am__objects_2) \
|
||||
$(am__objects_3)
|
||||
$(am__objects_3) $(am__objects_4) $(am__objects_5)
|
||||
libqb_la_OBJECTS = $(am_libqb_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
@ -127,7 +134,7 @@ libqb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libqb_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
@ -158,106 +165,8 @@ DATA = $(pkgconfig_DATA)
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
# If stdout is a non-dumb tty, use colors. If test -t is not supported,
|
||||
# then this fails; a conservative approach. Of course do not redirect
|
||||
# stdout here, just stderr.
|
||||
am__tty_colors = \
|
||||
red=; grn=; lgn=; blu=; std=; \
|
||||
test "X$(AM_COLOR_TESTS)" != Xno \
|
||||
&& test "X$$TERM" != Xdumb \
|
||||
&& { test "X$(AM_COLOR_TESTS)" = Xalways || test -t 1 2>/dev/null; } \
|
||||
&& { \
|
||||
red='[0;31m'; \
|
||||
grn='[0;32m'; \
|
||||
lgn='[1;32m'; \
|
||||
blu='[1;34m'; \
|
||||
std='[m'; \
|
||||
}
|
||||
# Restructured Text title and section.
|
||||
am__rst_title = sed 's/.*/ & /;h;s/./=/g;p;x;p;g;p;s/.*//'
|
||||
am__rst_section = sed 'p;s/./=/g;p;g'
|
||||
# Put stdin (possibly several lines separated by ". ") in a box.
|
||||
# Prefix each line by 'col' and terminate each with 'std', for coloring.
|
||||
# Multi line coloring is problematic with "less -R", so we really need
|
||||
# to color each line individually.
|
||||
am__text_box = $(AWK) '{ \
|
||||
n = split($$0, lines, "\\. "); max = 0; \
|
||||
for (i = 1; i <= n; ++i) \
|
||||
if (max < length(lines[i])) \
|
||||
max = length(lines[i]); \
|
||||
for (i = 0; i < max; ++i) \
|
||||
line = line "="; \
|
||||
print col line std; \
|
||||
for (i = 1; i <= n; ++i) \
|
||||
if (lines[i]) \
|
||||
print col lines[i] std; \
|
||||
print col line std; \
|
||||
}'
|
||||
# Solaris 10 'make', and several other traditional 'make' implementations,
|
||||
# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
|
||||
# by disabling -e (using the XSI extension "set +e") if it's set.
|
||||
am__sh_e_setup = case $$- in *e*) set +e;; esac
|
||||
# To be inserted before the command running the test. Creates the
|
||||
# directory for the log if needed. Stores in $dir the directory
|
||||
# containing $f, in $tst the test, in $log the log, and passes
|
||||
# TESTS_ENVIRONMENT. Save and restore TERM around use of
|
||||
# TESTS_ENVIRONMENT, in case that unsets it.
|
||||
am__check_pre = \
|
||||
$(am__sh_e_setup); \
|
||||
$(am__vpath_adj_setup) $(am__vpath_adj) \
|
||||
srcdir=$(srcdir); export srcdir; \
|
||||
rm -f $@-t; \
|
||||
am__trap='rm -f '\''$(abs_builddir)/$@-t'\''; (exit $$st); exit $$st'; \
|
||||
trap "st=129; $$am__trap" 1; trap "st=130; $$am__trap" 2; \
|
||||
trap "st=141; $$am__trap" 13; trap "st=143; $$am__trap" 15; \
|
||||
am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`; \
|
||||
test "x$$am__odir" = x. || $(MKDIR_P) "$$am__odir" || exit $$?; \
|
||||
if test -f "./$$f"; then dir=./; \
|
||||
elif test -f "$$f"; then dir=; \
|
||||
else dir="$(srcdir)/"; fi; \
|
||||
tst=$$dir$$f; log='$@'; __SAVED_TERM=$$TERM; \
|
||||
$(TESTS_ENVIRONMENT)
|
||||
# To be appended to the command running the test. Handle the stdout
|
||||
# and stderr redirection, and catch the exit status.
|
||||
am__check_post = \
|
||||
>$@-t 2>&1; \
|
||||
estatus=$$?; \
|
||||
if test -n '$(DISABLE_HARD_ERRORS)' \
|
||||
&& test $$estatus -eq 99; then \
|
||||
estatus=1; \
|
||||
fi; \
|
||||
TERM=$$__SAVED_TERM; export TERM; \
|
||||
$(am__tty_colors); \
|
||||
xfailed=PASS; \
|
||||
case " $(XFAIL_TESTS) " in \
|
||||
*[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
|
||||
xfailed=XFAIL;; \
|
||||
esac; \
|
||||
case $$estatus.$$xfailed in \
|
||||
0.XFAIL) col=$$red; res=XPASS;; \
|
||||
0.*) col=$$grn; res=PASS ;; \
|
||||
77.*) col=$$blu; res=SKIP ;; \
|
||||
99.*) col=$$red; res=FAIL ;; \
|
||||
*.XFAIL) col=$$lgn; res=XFAIL;; \
|
||||
*.*) col=$$red; res=FAIL ;; \
|
||||
esac; \
|
||||
echo "$${col}$$res$${std}: $$f"; \
|
||||
echo "$$res: $$f (exit: $$estatus)" | \
|
||||
$(am__rst_section) >$@; \
|
||||
cat $@-t >>$@; \
|
||||
rm -f $@-t
|
||||
RECHECK_LOGS = $(TEST_LOGS)
|
||||
AM_RECURSIVE_TARGETS = check recheck check-html recheck-html
|
||||
TEST_SUITE_HTML = $(TEST_SUITE_LOG:.log=.html)
|
||||
TEST_SUITE_LOG = test-suite.log
|
||||
TEST_EXTENSIONS = @EXEEXT@ .test
|
||||
LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
|
||||
am__test_logs1 = $(TESTS:=.log)
|
||||
am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
|
||||
TEST_LOGS = $(am__test_logs2:.test.log=.log)
|
||||
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
|
||||
$(TEST_LOG_FLAGS)
|
||||
TEST_LOGS_TMP = $(TEST_LOGS:.log=.log-t)
|
||||
red=; grn=; lgn=; blu=; std=
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
@ -305,7 +214,6 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_RT = @LIB_RT@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
@ -393,43 +301,69 @@ top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h log_int.h map_int.h
|
||||
noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h \
|
||||
log_int.h map_int.h rpl_sem.h loop_poll_int.h
|
||||
|
||||
#
|
||||
# Here are a set of rules to help you update your library version information:
|
||||
# Start with version information of ‘0:0:0’ for each libtool library.
|
||||
# Update the version information only immediately before a public release of your software.
|
||||
# More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster.
|
||||
# If the library source code has changed at all since the last update, then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
|
||||
# If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
|
||||
# If any interfaces have been added since the last public release, then increment age.
|
||||
# If any interfaces have been removed since the last public release, then set age to 0.
|
||||
#
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
lib_LTLIBRARIES = libqb.la
|
||||
libqb_la_LDFLAGS = -version-info 11:1:11
|
||||
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \
|
||||
loop.c loop_poll.c loop_job.c loop_timerlist.c \
|
||||
ipcc.c ipcs.c ipc_shm.c ipc_us.c \
|
||||
|
||||
# From: http://sourceware.org/autobook/autobook/autobook_91.html
|
||||
# (for my own sanity).
|
||||
#
|
||||
# 1) If you have changed any of the sources for this library, the revision
|
||||
# number must be incremented. This is a new revision of the current
|
||||
# interface.
|
||||
#
|
||||
# 2) If the interface has changed, then current must be incremented, and
|
||||
# revision reset to `0'. This is the first revision of a new interface.
|
||||
#
|
||||
# 3) If the new interface is a superset of the previous interface
|
||||
# (that is, if the previous interface has not been broken by the changes
|
||||
# in this new release), then age must be incremented. This release is
|
||||
# backwards compatible with the previous release.
|
||||
#
|
||||
# 4) If the new interface has removed elements with respect to the previous
|
||||
# interface, then you have broken backward compatibility and age must be
|
||||
# reset to `0'. This release has a new, but backwards incompatible
|
||||
# interface. For example, if the next release of the library included
|
||||
# some new commands for an existing socket protocol, you would use
|
||||
# -version-info 1:0:1. This is the first revision of a new interface.
|
||||
# This release is backwards compatible with the previous release.
|
||||
# Later, you implement a faster way of handling part of the algorithm
|
||||
# at the core of the library, and release it with -version-info 1:1:1.
|
||||
# This is a new revision of the current interface.
|
||||
# Unfortunately the speed of your new implementation can only be fully
|
||||
# exploited by changing the API to access the structures at a lower level,
|
||||
# which breaks compatibility with the previous interface, so you release
|
||||
# it as -version-info 2:0:0. This release has a new, but backwards
|
||||
# incompatible interface.
|
||||
#
|
||||
libqb_la_LDFLAGS = -version-info 14:2:14
|
||||
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
|
||||
array.c loop.c loop_poll.c loop_job.c \
|
||||
loop_timerlist.c ipcc.c ipcs.c ipc_shm.c ipc_us.c \
|
||||
log.c log_thread.c log_blackbox.c log_file.c \
|
||||
log_syslog.c log_dcs.c log_format.c \
|
||||
map.c skiplist.c hashtable.c trie.c
|
||||
|
||||
libqb_la_SOURCES = $(source_to_lint) unix.c $(am__append_1) \
|
||||
$(am__append_2)
|
||||
$(am__append_2) $(am__append_3) $(am__append_4)
|
||||
libqb_la_LIBADD = @LTLIBOBJS@
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libqb.pc
|
||||
@HAVE_SPLINT_TRUE@check_SCRIPTS = run_splint.sh
|
||||
@HAVE_SPLINT_TRUE@TESTS = $(check_SCRIPTS)
|
||||
@HAVE_SPLINT_TRUE@ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
# this is a hack because debian/ubuntu don't set the arch path
|
||||
# in splint.
|
||||
@HAVE_SPLINT_TRUE@DEB_INCLUDES = -I/usr/include/x86_64-linux-gnu -I/usr/include/i386-linux-gnu
|
||||
@HAVE_SPLINT_TRUE@ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DEB_INCLUDES) \
|
||||
@HAVE_SPLINT_TRUE@ $(libqb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CPPFLAGS) \
|
||||
@HAVE_SPLINT_TRUE@ $(LINT_FLAGS)
|
||||
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .html .lo .log .o .obj .test .test$(EXEEXT)
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
@ -508,9 +442,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtable.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_posix_mq.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_shm.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_sysv_mq.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_us.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipcc.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipcs.Plo@am__quote@
|
||||
@ -524,10 +456,14 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_job.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll_epoll.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll_kqueue.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll_poll.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_timerlist.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ringbuffer.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ringbuffer_helper.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpl_sem.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skiplist.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trie.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@
|
||||
@ -630,139 +566,98 @@ GTAGS:
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
$(TEST_SUITE_LOG): $(TEST_LOGS)
|
||||
@$(am__sh_e_setup); \
|
||||
list='$(TEST_LOGS)'; \
|
||||
results=`for f in $$list; do \
|
||||
test -r $$f && read line < $$f && echo "$$line" \
|
||||
|| echo FAIL; \
|
||||
done`; \
|
||||
all=`echo "$$results" | sed '/^$$/d' | wc -l | sed -e 's/^[ ]*//'`; \
|
||||
fail=`echo "$$results" | grep -c '^FAIL'`; \
|
||||
pass=`echo "$$results" | grep -c '^PASS'`; \
|
||||
skip=`echo "$$results" | grep -c '^SKIP'`; \
|
||||
xfail=`echo "$$results" | grep -c '^XFAIL'`; \
|
||||
xpass=`echo "$$results" | grep -c '^XPASS'`; \
|
||||
failures=`expr $$fail + $$xpass`; \
|
||||
all=`expr $$all - $$skip`; \
|
||||
if test "$$all" -eq 1; then tests=test; All=; \
|
||||
else tests=tests; All="All "; fi; \
|
||||
case fail=$$fail:xpass=$$xpass:xfail=$$xfail in \
|
||||
fail=0:xpass=0:xfail=0) \
|
||||
msg="$$All$$all $$tests passed. "; \
|
||||
exit=true;; \
|
||||
fail=0:xpass=0:xfail=*) \
|
||||
msg="$$All$$all $$tests behaved as expected"; \
|
||||
if test "$$xfail" -eq 1; then xfailures=failure; \
|
||||
else xfailures=failures; fi; \
|
||||
msg="$$msg ($$xfail expected $$xfailures). "; \
|
||||
exit=true;; \
|
||||
fail=*:xpass=0:xfail=*) \
|
||||
msg="$$fail of $$all $$tests failed. "; \
|
||||
exit=false;; \
|
||||
fail=*:xpass=*:xfail=*) \
|
||||
msg="$$failures of $$all $$tests did not behave as expected"; \
|
||||
if test "$$xpass" -eq 1; then xpasses=pass; \
|
||||
else xpasses=passes; fi; \
|
||||
msg="$$msg ($$xpass unexpected $$xpasses). "; \
|
||||
exit=false;; \
|
||||
*) \
|
||||
echo >&2 "incorrect case"; exit 4;; \
|
||||
esac; \
|
||||
if test "$$skip" -ne 0; then \
|
||||
if test "$$skip" -eq 1; then \
|
||||
msg="$$msg($$skip test was not run). "; \
|
||||
else \
|
||||
msg="$$msg($$skip tests were not run). "; \
|
||||
fi; \
|
||||
fi; \
|
||||
{ \
|
||||
echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
|
||||
$(am__rst_title); \
|
||||
echo "$$msg"; \
|
||||
echo; \
|
||||
echo ".. contents:: :depth: 2"; \
|
||||
echo; \
|
||||
for f in $$list; do \
|
||||
test -r $$f && read line < $$f || line=; \
|
||||
case $$line in \
|
||||
PASS:*|XFAIL:*);; \
|
||||
*) echo; cat $$f;; \
|
||||
esac; \
|
||||
done; \
|
||||
} >$(TEST_SUITE_LOG).tmp; \
|
||||
mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
|
||||
if test "$$failures" -ne 0; then \
|
||||
msg="$${msg}See $(subdir)/$(TEST_SUITE_LOG). "; \
|
||||
if test -n "$(PACKAGE_BUGREPORT)"; then \
|
||||
msg="$${msg}Please report to $(PACKAGE_BUGREPORT). "; \
|
||||
fi; \
|
||||
fi; \
|
||||
test x"$$VERBOSE" = x || $$exit || cat $(TEST_SUITE_LOG); \
|
||||
$(am__tty_colors); \
|
||||
if $$exit; then \
|
||||
col="$$grn"; \
|
||||
else \
|
||||
col="$$red"; \
|
||||
fi; \
|
||||
echo "$$msg" | $(am__text_box) "col=$$col" "std=$$std"; \
|
||||
$$exit || exit 1
|
||||
|
||||
check-TESTS recheck:
|
||||
@if test $@ != recheck; then \
|
||||
list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list; \
|
||||
fi
|
||||
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
|
||||
@list='' list2='$(TEST_LOGS)'; for f in $$list2; do \
|
||||
test .log = $$f && continue; \
|
||||
if test $@ = recheck; then \
|
||||
test -f $$f || continue; \
|
||||
if test -r $$f && read line < $$f; then \
|
||||
case $$line in FAIL*|XPASS*) : ;; *) continue;; esac; \
|
||||
check-TESTS: $(TESTS)
|
||||
@failed=0; all=0; xfail=0; xpass=0; skip=0; \
|
||||
srcdir=$(srcdir); export srcdir; \
|
||||
list=' $(TESTS) '; \
|
||||
$(am__tty_colors); \
|
||||
if test -n "$$list"; then \
|
||||
for tst in $$list; do \
|
||||
if test -f ./$$tst; then dir=./; \
|
||||
elif test -f $$tst; then dir=; \
|
||||
else dir="$(srcdir)/"; fi; \
|
||||
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
|
||||
all=`expr $$all + 1`; \
|
||||
case " $(XFAIL_TESTS) " in \
|
||||
*[\ \ ]$$tst[\ \ ]*) \
|
||||
xpass=`expr $$xpass + 1`; \
|
||||
failed=`expr $$failed + 1`; \
|
||||
col=$$red; res=XPASS; \
|
||||
;; \
|
||||
*) \
|
||||
col=$$grn; res=PASS; \
|
||||
;; \
|
||||
esac; \
|
||||
elif test $$? -ne 77; then \
|
||||
all=`expr $$all + 1`; \
|
||||
case " $(XFAIL_TESTS) " in \
|
||||
*[\ \ ]$$tst[\ \ ]*) \
|
||||
xfail=`expr $$xfail + 1`; \
|
||||
col=$$lgn; res=XFAIL; \
|
||||
;; \
|
||||
*) \
|
||||
failed=`expr $$failed + 1`; \
|
||||
col=$$red; res=FAIL; \
|
||||
;; \
|
||||
esac; \
|
||||
else \
|
||||
skip=`expr $$skip + 1`; \
|
||||
col=$$blu; res=SKIP; \
|
||||
fi; \
|
||||
echo "$${col}$$res$${std}: $$tst"; \
|
||||
done; \
|
||||
if test "$$all" -eq 1; then \
|
||||
tests="test"; \
|
||||
All=""; \
|
||||
else \
|
||||
tests="tests"; \
|
||||
All="All "; \
|
||||
fi; \
|
||||
if test "$$failed" -eq 0; then \
|
||||
if test "$$xfail" -eq 0; then \
|
||||
banner="$$All$$all $$tests passed"; \
|
||||
else \
|
||||
if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
|
||||
banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
|
||||
fi; \
|
||||
else \
|
||||
if test "$$xpass" -eq 0; then \
|
||||
banner="$$failed of $$all $$tests failed"; \
|
||||
else \
|
||||
if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
|
||||
banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
|
||||
fi; \
|
||||
fi; \
|
||||
if test -z "$$list"; then list=$$f; else list="$$list $$f"; fi; \
|
||||
done; \
|
||||
if test $@ = recheck && test -n "$$list"; then \
|
||||
echo "am--clean: ; rm -f $$list" \
|
||||
| $(MAKE) $(AM_MAKEFLAGS) -f - am--clean || exit 1; \
|
||||
fi; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$list"
|
||||
recheck: $(check_SCRIPTS)
|
||||
|
||||
am--mostlyclean-test-html:
|
||||
list='$(TEST_LOGS:.log=.html)'; test -z "$$list" || rm -f $$list
|
||||
rm -f $(TEST_SUITE_HTML)
|
||||
|
||||
.log.html:
|
||||
@list='$(RST2HTML) $$RST2HTML rst2html rst2html.py'; \
|
||||
for r2h in $$list; do \
|
||||
if ($$r2h --version) >/dev/null 2>&1; then \
|
||||
R2H=$$r2h; \
|
||||
fi; \
|
||||
done; \
|
||||
if test -z "$$R2H"; then \
|
||||
echo >&2 "cannot find rst2html, cannot create $@"; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
$$R2H $< >$@.tmp
|
||||
@mv $@.tmp $@
|
||||
|
||||
# Be sure to run check first, and then to convert the result.
|
||||
# Beware of concurrent executions. Run "check" not "check-TESTS", as
|
||||
# check-SCRIPTS and other dependencies are rebuilt by the former only.
|
||||
# And expect check to fail.
|
||||
check-html recheck-html:
|
||||
@target=`echo $@ | sed 's/-html$$//'`; \
|
||||
rv=0; $(MAKE) $(AM_MAKEFLAGS) $$target || rv=$$?; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_HTML) TEST_LOGS= || exit 4; \
|
||||
exit $$rv
|
||||
run_splint.sh.log: run_splint.sh
|
||||
@p='run_splint.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
.test.log:
|
||||
@p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
@am__EXEEXT_TRUE@.test$(EXEEXT).log:
|
||||
@am__EXEEXT_TRUE@ @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
dashes="$$banner"; \
|
||||
skipped=""; \
|
||||
if test "$$skip" -ne 0; then \
|
||||
if test "$$skip" -eq 1; then \
|
||||
skipped="($$skip test was not run)"; \
|
||||
else \
|
||||
skipped="($$skip tests were not run)"; \
|
||||
fi; \
|
||||
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
|
||||
dashes="$$skipped"; \
|
||||
fi; \
|
||||
report=""; \
|
||||
if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
|
||||
report="Please report to $(PACKAGE_BUGREPORT)"; \
|
||||
test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
|
||||
dashes="$$report"; \
|
||||
fi; \
|
||||
dashes=`echo "$$dashes" | sed s/./=/g`; \
|
||||
if test "$$failed" -eq 0; then \
|
||||
col="$$grn"; \
|
||||
else \
|
||||
col="$$red"; \
|
||||
fi; \
|
||||
echo "$${col}$$dashes$${std}"; \
|
||||
echo "$${col}$$banner$${std}"; \
|
||||
test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
|
||||
test -z "$$report" || echo "$${col}$$report$${std}"; \
|
||||
echo "$${col}$$dashes$${std}"; \
|
||||
test "$$failed" -eq 0; \
|
||||
else :; fi
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
@ -823,9 +718,6 @@ install-strip:
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
|
||||
-test -z "$(TEST_LOGS_TMP)" || rm -f $(TEST_LOGS_TMP)
|
||||
-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
|
||||
|
||||
@HAVE_SPLINT_FALSE@clean-generic:
|
||||
|
||||
@ -895,8 +787,8 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: am--mostlyclean-test-html mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
@ -908,22 +800,21 @@ ps-am:
|
||||
|
||||
uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigDATA
|
||||
|
||||
.MAKE: check-am check-html install-am install-strip recheck-html
|
||||
.MAKE: check-am install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am am--mostlyclean-test-html check \
|
||||
check-TESTS check-am check-html clean clean-generic \
|
||||
clean-libLTLIBRARIES clean-libtool ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am \
|
||||
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
|
||||
install-pkgconfigDATA install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
recheck recheck-html tags uninstall uninstall-am \
|
||||
.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
|
||||
clean-generic clean-libLTLIBRARIES clean-libtool ctags \
|
||||
distclean distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-libLTLIBRARIES install-man install-pdf \
|
||||
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
pdf pdf-am ps ps-am tags uninstall uninstall-am \
|
||||
uninstall-libLTLIBRARIES uninstall-pkgconfigDATA
|
||||
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ qb_array_index(struct qb_array * a, int32_t idx, void **element_out)
|
||||
int32_t b;
|
||||
int32_t elem;
|
||||
char *bin;
|
||||
int32_t rc;
|
||||
int32_t rc = 0;
|
||||
|
||||
if (a == NULL || element_out == NULL) {
|
||||
return -EINVAL;
|
||||
@ -207,6 +207,7 @@ qb_array_free(struct qb_array *a)
|
||||
for (i = 0; i < a->num_bins; i++) {
|
||||
free(a->bin[i]);
|
||||
}
|
||||
free(a->bin);
|
||||
(void)qb_thread_lock_destroy(a->grow_lock);
|
||||
free(a);
|
||||
}
|
||||
|
||||
@ -25,9 +25,6 @@
|
||||
#include "os_base.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#ifdef HAVE_MQUEUE_H
|
||||
#include <mqueue.h>
|
||||
#endif /* HAVE_MQUEUE_H */
|
||||
#include <qb/qblist.h>
|
||||
#include <qb/qbloop.h>
|
||||
#include <qb/qbipcc.h>
|
||||
@ -35,10 +32,6 @@
|
||||
#include <qb/qbipc_common.h>
|
||||
#include <qb/qbrb.h>
|
||||
|
||||
#ifdef HAVE_POSIX_SHARED_SEMAPHORE
|
||||
#include <semaphore.h>
|
||||
#endif /* HAVE_POSIX_SHARED_SEMAPHORE */
|
||||
|
||||
#define QB_IPC_MAX_WAIT_MS 2000
|
||||
|
||||
/*
|
||||
@ -50,23 +43,23 @@ SEND CONN REQ ->
|
||||
*/
|
||||
|
||||
struct qb_ipc_connection_request {
|
||||
struct qb_ipc_request_header hdr __attribute__ ((aligned(8)));
|
||||
uint32_t max_msg_size __attribute__ ((aligned(8)));
|
||||
struct qb_ipc_request_header hdr;
|
||||
uint32_t max_msg_size;
|
||||
} __attribute__ ((aligned(8)));
|
||||
|
||||
struct qb_ipc_event_connection_request {
|
||||
struct qb_ipc_request_header hdr __attribute__ ((aligned(8)));
|
||||
intptr_t connection __attribute__ ((aligned(8)));
|
||||
struct qb_ipc_request_header hdr;
|
||||
intptr_t connection;
|
||||
} __attribute__ ((aligned(8)));
|
||||
|
||||
struct qb_ipc_connection_response {
|
||||
struct qb_ipc_response_header hdr __attribute__ ((aligned(8)));
|
||||
int32_t connection_type __attribute__ ((aligned(8)));
|
||||
uint32_t max_msg_size __attribute__ ((aligned(8)));
|
||||
intptr_t connection __attribute__ ((aligned(8)));
|
||||
char request[PATH_MAX] __attribute__ ((aligned(8)));
|
||||
char response[PATH_MAX] __attribute__ ((aligned(8)));
|
||||
char event[PATH_MAX] __attribute__ ((aligned(8)));
|
||||
struct qb_ipc_response_header hdr;
|
||||
int32_t connection_type;
|
||||
uint32_t max_msg_size;
|
||||
intptr_t connection;
|
||||
char request[PATH_MAX];
|
||||
char response[PATH_MAX];
|
||||
char event[PATH_MAX];
|
||||
} __attribute__ ((aligned(8)));
|
||||
|
||||
struct qb_ipcc_connection;
|
||||
@ -80,16 +73,6 @@ struct qb_ipc_one_way {
|
||||
void* shared_data;
|
||||
char shared_file_name[NAME_MAX];
|
||||
} us;
|
||||
#ifdef HAVE_MQUEUE_H
|
||||
struct {
|
||||
mqd_t q;
|
||||
char name[NAME_MAX];
|
||||
} pmq;
|
||||
#endif
|
||||
struct {
|
||||
int32_t q;
|
||||
int32_t key;
|
||||
} smq;
|
||||
struct {
|
||||
qb_ringbuffer_t *rb;
|
||||
} shm;
|
||||
@ -122,13 +105,11 @@ int32_t qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
|
||||
struct qb_ipc_connection_response *r);
|
||||
ssize_t qb_ipc_us_send(struct qb_ipc_one_way *one_way, const void *msg, size_t len);
|
||||
ssize_t qb_ipc_us_recv(struct qb_ipc_one_way *one_way, void *msg, size_t len, int32_t timeout);
|
||||
int32_t qb_ipc_us_recv_ready(struct qb_ipc_one_way *one_way, int32_t ms_timeout);
|
||||
int32_t qb_ipc_us_ready(struct qb_ipc_one_way *one_way, int32_t ms_timeout, int32_t events);
|
||||
|
||||
void qb_ipcc_us_sock_close(int32_t sock);
|
||||
|
||||
int32_t qb_ipcc_pmq_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response);
|
||||
int32_t qb_ipcc_us_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response);
|
||||
int32_t qb_ipcc_smq_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response);
|
||||
int32_t qb_ipcc_shm_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response);
|
||||
|
||||
struct qb_ipcs_service;
|
||||
@ -173,12 +154,21 @@ enum qb_ipcs_connection_state {
|
||||
QB_IPCS_CONNECTION_SHUTTING_DOWN,
|
||||
};
|
||||
|
||||
#define CONNECTION_DESCRIPTION (16)
|
||||
|
||||
struct qb_ipcs_connection_auth {
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
};
|
||||
|
||||
struct qb_ipcs_connection {
|
||||
enum qb_ipcs_connection_state state;
|
||||
int32_t refcount;
|
||||
pid_t pid;
|
||||
uid_t euid;
|
||||
gid_t egid;
|
||||
struct qb_ipcs_connection_auth auth;
|
||||
struct qb_ipc_one_way setup;
|
||||
struct qb_ipc_one_way request;
|
||||
struct qb_ipc_one_way response;
|
||||
@ -190,12 +180,11 @@ struct qb_ipcs_connection {
|
||||
int32_t fc_enabled;
|
||||
int32_t poll_events;
|
||||
int32_t outstanding_notifiers;
|
||||
struct qb_ipcs_connection_stats stats;
|
||||
char description[CONNECTION_DESCRIPTION];
|
||||
struct qb_ipcs_connection_stats_2 stats;
|
||||
};
|
||||
|
||||
void qb_ipcs_pmq_init(struct qb_ipcs_service *s);
|
||||
void qb_ipcs_us_init(struct qb_ipcs_service *s);
|
||||
void qb_ipcs_smq_init(struct qb_ipcs_service *s);
|
||||
void qb_ipcs_shm_init(struct qb_ipcs_service *s);
|
||||
|
||||
int32_t qb_ipcs_us_publish(struct qb_ipcs_service *s);
|
||||
@ -204,8 +193,11 @@ int32_t qb_ipcs_us_withdraw(struct qb_ipcs_service *s);
|
||||
int32_t qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data);
|
||||
int32_t qb_ipcs_dispatch_service_request(int32_t fd, int32_t revents, void *data);
|
||||
struct qb_ipcs_connection* qb_ipcs_connection_alloc(struct qb_ipcs_service *s);
|
||||
void qb_ipcs_sockets_disconnect(struct qb_ipcs_connection *c);
|
||||
|
||||
int32_t qb_ipcs_process_request(struct qb_ipcs_service *s,
|
||||
struct qb_ipc_request_header *hdr);
|
||||
|
||||
int32_t qb_ipc_us_sock_error_is_disconnected(int err);
|
||||
|
||||
#endif /* QB_IPC_INT_H_DEFINED */
|
||||
|
||||
@ -1,421 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* Author: Angus Salkeld <asalkeld@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "os_base.h"
|
||||
|
||||
#include <mqueue.h>
|
||||
#include <sys/resource.h>
|
||||
#include "ipc_int.h"
|
||||
#include "util_int.h"
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qbloop.h>
|
||||
|
||||
#define QB_REQUEST_Q_LEN 3
|
||||
#define QB_RESPONSE_Q_LEN 1
|
||||
#define QB_EVENT_Q_LEN 3
|
||||
|
||||
static size_t q_space_used = 0;
|
||||
#ifdef QB_LINUX
|
||||
#define QB_RLIMIT_CHANGE_NEEDED 1
|
||||
#endif /* QB_LINUX */
|
||||
|
||||
/*
|
||||
* utility functions
|
||||
* --------------------------------------------------------
|
||||
*/
|
||||
static int32_t
|
||||
posix_mq_increase_limits(size_t max_msg_size, int32_t q_len)
|
||||
{
|
||||
int32_t res = 0;
|
||||
#ifdef QB_RLIMIT_CHANGE_NEEDED
|
||||
struct rlimit rlim;
|
||||
size_t q_space_needed;
|
||||
#endif /* QB_RLIMIT_CHANGE_NEEDED */
|
||||
|
||||
#ifdef QB_RLIMIT_CHANGE_NEEDED
|
||||
if (getrlimit(RLIMIT_MSGQUEUE, &rlim) != 0) {
|
||||
res = -errno;
|
||||
qb_util_log(LOG_ERR, "getrlimit failed");
|
||||
return res;
|
||||
}
|
||||
q_space_needed = q_space_used + (max_msg_size * q_len * 4 / 3);
|
||||
|
||||
qb_util_log(LOG_DEBUG, "rlimit:%d needed:%zu used:%zu",
|
||||
(int)rlim.rlim_cur, q_space_needed, q_space_used);
|
||||
|
||||
if (rlim.rlim_cur < q_space_needed) {
|
||||
rlim.rlim_cur = q_space_needed;
|
||||
}
|
||||
if (rlim.rlim_max < q_space_needed) {
|
||||
rlim.rlim_max = q_space_needed;
|
||||
}
|
||||
if (setrlimit(RLIMIT_MSGQUEUE, &rlim) != 0) {
|
||||
res = -errno;
|
||||
qb_util_log(LOG_ERR, "setrlimit failed");
|
||||
}
|
||||
#endif /* QB_RLIMIT_CHANGE_NEEDED */
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
posix_mq_open(struct qb_ipc_one_way *one_way, const char *name, size_t q_len)
|
||||
{
|
||||
int32_t res = posix_mq_increase_limits(one_way->max_msg_size, q_len);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
one_way->u.pmq.q = mq_open(name, O_RDWR);
|
||||
if (one_way->u.pmq.q == (mqd_t) - 1) {
|
||||
res = -errno;
|
||||
perror("mq_open");
|
||||
return res;
|
||||
}
|
||||
(void)strlcpy(one_way->u.pmq.name, name, NAME_MAX);
|
||||
q_space_used += one_way->max_msg_size * q_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
posix_mq_create(struct qb_ipcs_connection *c,
|
||||
struct qb_ipc_one_way *one_way, const char *name, size_t q_len)
|
||||
{
|
||||
struct mq_attr attr;
|
||||
mqd_t q = 0;
|
||||
int32_t res = 0;
|
||||
mode_t m = 0600;
|
||||
size_t max_msg_size = one_way->max_msg_size;
|
||||
|
||||
res = posix_mq_increase_limits(max_msg_size, q_len);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
try_smaller:
|
||||
if (q != 0) {
|
||||
max_msg_size = max_msg_size / 2;
|
||||
q_len--;
|
||||
}
|
||||
attr.mq_flags = O_NONBLOCK;
|
||||
attr.mq_maxmsg = q_len;
|
||||
attr.mq_msgsize = max_msg_size;
|
||||
|
||||
q = mq_open(name, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, m, &attr);
|
||||
if (q == (mqd_t) - 1 && errno == ENOMEM) {
|
||||
if (max_msg_size > 9000 && q_len > 3) {
|
||||
goto try_smaller;
|
||||
}
|
||||
}
|
||||
if (q == (mqd_t) - 1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "Can't create mq \"%s\"", name);
|
||||
return res;
|
||||
}
|
||||
q_space_used += max_msg_size * q_len;
|
||||
one_way->max_msg_size = max_msg_size;
|
||||
one_way->u.pmq.q = q;
|
||||
(void)strlcpy(one_way->u.pmq.name, name, NAME_MAX);
|
||||
|
||||
res = fchown((int)q, c->euid, c->egid);
|
||||
if (res == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "fchown:%s", name);
|
||||
mq_close(q);
|
||||
mq_unlink(name);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qb_ipc_pmq_send(struct qb_ipc_one_way *one_way,
|
||||
const void *msg_ptr, size_t msg_len)
|
||||
{
|
||||
int32_t res = mq_send(one_way->u.pmq.q, msg_ptr, msg_len, 1);
|
||||
if (res != 0) {
|
||||
return -errno;
|
||||
}
|
||||
return msg_len;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qb_ipc_pmq_sendv(struct qb_ipc_one_way *one_way,
|
||||
const struct iovec *iov, size_t iov_len)
|
||||
{
|
||||
int32_t total_size = 0;
|
||||
int32_t i;
|
||||
int32_t res = 0;
|
||||
char *data = NULL;
|
||||
char *pt = NULL;
|
||||
|
||||
for (i = 0; i < iov_len; i++) {
|
||||
total_size += iov[i].iov_len;
|
||||
}
|
||||
if (total_size == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
data = malloc(total_size);
|
||||
if (data == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
pt = data;
|
||||
|
||||
for (i = 0; i < iov_len; i++) {
|
||||
memcpy(pt, iov[i].iov_base, iov[i].iov_len);
|
||||
pt += iov[i].iov_len;
|
||||
}
|
||||
|
||||
res = mq_send(one_way->u.pmq.q, data, total_size, 1);
|
||||
free(data);
|
||||
if (res != 0) {
|
||||
return -errno;
|
||||
}
|
||||
return total_size;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qb_ipc_pmq_recv(struct qb_ipc_one_way *one_way,
|
||||
void *msg_ptr, size_t msg_len, int32_t ms_timeout)
|
||||
{
|
||||
uint32_t msg_prio;
|
||||
struct timespec ts_timeout;
|
||||
ssize_t res;
|
||||
|
||||
if (ms_timeout >= 0) {
|
||||
qb_util_timespec_from_epoch_get(&ts_timeout);
|
||||
qb_timespec_add_ms(&ts_timeout, ms_timeout);
|
||||
}
|
||||
|
||||
mq_receive_again:
|
||||
if (ms_timeout >= 0) {
|
||||
res = mq_timedreceive(one_way->u.pmq.q,
|
||||
(char *)msg_ptr,
|
||||
one_way->max_msg_size,
|
||||
&msg_prio, &ts_timeout);
|
||||
} else {
|
||||
res = mq_receive(one_way->u.pmq.q,
|
||||
(char *)msg_ptr,
|
||||
one_way->max_msg_size, &msg_prio);
|
||||
}
|
||||
if (res == -1) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
goto mq_receive_again;
|
||||
break;
|
||||
case EAGAIN:
|
||||
res = -ETIMEDOUT;
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
res = -errno;
|
||||
break;
|
||||
default:
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR,
|
||||
"error waiting for mq_timedreceive");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* client functions
|
||||
* --------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
qb_ipcc_pmq_disconnect(struct qb_ipcc_connection *c)
|
||||
{
|
||||
struct qb_ipc_request_header hdr;
|
||||
|
||||
qb_util_log(LOG_DEBUG, "%s()", __func__);
|
||||
if (c->needs_sock_for_poll) {
|
||||
return;
|
||||
}
|
||||
|
||||
hdr.id = QB_IPC_MSG_DISCONNECT;
|
||||
hdr.size = sizeof(hdr);
|
||||
mq_send(c->request.u.pmq.q, (const char *)&hdr, hdr.size, 30);
|
||||
|
||||
mq_close(c->event.u.pmq.q);
|
||||
mq_close(c->response.u.pmq.q);
|
||||
mq_close(c->request.u.pmq.q);
|
||||
|
||||
mq_unlink(c->event.u.pmq.name);
|
||||
mq_unlink(c->request.u.pmq.name);
|
||||
mq_unlink(c->response.u.pmq.name);
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_ipcc_pmq_connect(struct qb_ipcc_connection *c,
|
||||
struct qb_ipc_connection_response *response)
|
||||
{
|
||||
int32_t res = 0;
|
||||
|
||||
c->funcs.send = qb_ipc_pmq_send;
|
||||
c->funcs.sendv = qb_ipc_pmq_sendv;
|
||||
c->funcs.recv = qb_ipc_pmq_recv;
|
||||
c->funcs.fc_get = NULL;
|
||||
c->funcs.disconnect = qb_ipcc_pmq_disconnect;
|
||||
#if defined(QB_LINUX) || defined(QB_BSD)
|
||||
c->needs_sock_for_poll = QB_FALSE;
|
||||
#else
|
||||
c->needs_sock_for_poll = QB_TRUE;
|
||||
#endif
|
||||
|
||||
if (strlen(c->name) > (NAME_MAX - 20)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = posix_mq_open(&c->request, response->request, QB_REQUEST_Q_LEN);
|
||||
if (res != 0) {
|
||||
perror("mq_open:REQUEST");
|
||||
return res;
|
||||
}
|
||||
res = posix_mq_open(&c->response, response->response,
|
||||
QB_RESPONSE_Q_LEN);
|
||||
if (res != 0) {
|
||||
perror("mq_open:RESPONSE");
|
||||
goto cleanup_request;
|
||||
}
|
||||
res = posix_mq_open(&c->event, response->event, QB_EVENT_Q_LEN);
|
||||
if (res != 0) {
|
||||
perror("mq_open:EVENT");
|
||||
goto cleanup_request_response;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup_request_response:
|
||||
mq_close(c->response.u.pmq.q);
|
||||
|
||||
cleanup_request:
|
||||
mq_close(c->request.u.pmq.q);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* service functions
|
||||
* --------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
qb_ipcs_pmq_disconnect(struct qb_ipcs_connection *c)
|
||||
{
|
||||
struct qb_ipc_response_header msg;
|
||||
|
||||
msg.id = QB_IPC_MSG_DISCONNECT;
|
||||
msg.size = sizeof(msg);
|
||||
msg.error = 0;
|
||||
|
||||
(void)qb_ipc_pmq_send(&c->event, &msg, msg.size);
|
||||
|
||||
mq_close(c->event.u.pmq.q);
|
||||
mq_close(c->response.u.pmq.q);
|
||||
mq_close(c->request.u.pmq.q);
|
||||
|
||||
mq_unlink(c->event.u.pmq.name);
|
||||
mq_unlink(c->request.u.pmq.name);
|
||||
mq_unlink(c->response.u.pmq.name);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
qb_ipcs_pmq_connect(struct qb_ipcs_service *s,
|
||||
struct qb_ipcs_connection *c,
|
||||
struct qb_ipc_connection_response *r)
|
||||
{
|
||||
int32_t res = 0;
|
||||
|
||||
snprintf(r->request, NAME_MAX, "/%s-request-%d", s->name, c->pid);
|
||||
snprintf(r->response, NAME_MAX, "/%s-response-%d", s->name, c->pid);
|
||||
snprintf(r->event, NAME_MAX, "/%s-event-%d", s->name, c->pid);
|
||||
|
||||
res = posix_mq_create(c, &c->request, r->request, QB_REQUEST_Q_LEN);
|
||||
if (res < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
res = posix_mq_create(c, &c->response, r->response, QB_RESPONSE_Q_LEN);
|
||||
if (res < 0) {
|
||||
goto cleanup_request;
|
||||
}
|
||||
|
||||
res = posix_mq_create(c, &c->event, r->event, QB_EVENT_Q_LEN);
|
||||
if (res < 0) {
|
||||
goto cleanup_request_response;
|
||||
}
|
||||
|
||||
if (!s->needs_sock_for_poll) {
|
||||
res =
|
||||
s->poll_fns.dispatch_add(s->poll_priority,
|
||||
(int32_t) c->request.u.pmq.q,
|
||||
POLLIN | POLLPRI | POLLNVAL, c,
|
||||
qb_ipcs_dispatch_service_request);
|
||||
}
|
||||
|
||||
r->hdr.error = 0;
|
||||
return res;
|
||||
|
||||
cleanup_request_response:
|
||||
mq_close(c->response.u.pmq.q);
|
||||
mq_unlink(r->response);
|
||||
cleanup_request:
|
||||
mq_close(c->request.u.pmq.q);
|
||||
mq_unlink(r->request);
|
||||
|
||||
cleanup:
|
||||
r->hdr.error = res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qb_ipc_pmq_q_len_get(struct qb_ipc_one_way *one_way)
|
||||
{
|
||||
struct mq_attr info;
|
||||
int32_t res = mq_getattr(one_way->u.pmq.q, &info);
|
||||
if (res == 0) {
|
||||
return info.mq_curmsgs;
|
||||
}
|
||||
return -errno;
|
||||
}
|
||||
|
||||
void
|
||||
qb_ipcs_pmq_init(struct qb_ipcs_service *s)
|
||||
{
|
||||
s->funcs.connect = qb_ipcs_pmq_connect;
|
||||
s->funcs.disconnect = qb_ipcs_pmq_disconnect;
|
||||
|
||||
s->funcs.recv = qb_ipc_pmq_recv;
|
||||
s->funcs.send = qb_ipc_pmq_send;
|
||||
s->funcs.sendv = qb_ipc_pmq_sendv;
|
||||
s->funcs.peek = NULL;
|
||||
s->funcs.reclaim = NULL;
|
||||
|
||||
s->funcs.fc_set = NULL;
|
||||
s->funcs.q_len_get = qb_ipc_pmq_q_len_get;
|
||||
|
||||
#if defined(QB_LINUX) || defined(QB_BSD)
|
||||
s->needs_sock_for_poll = QB_FALSE;
|
||||
#else
|
||||
s->needs_sock_for_poll = QB_TRUE;
|
||||
#endif
|
||||
}
|
||||
@ -106,10 +106,15 @@ static ssize_t
|
||||
qb_ipc_shm_peek(struct qb_ipc_one_way *one_way, void **data_out,
|
||||
int32_t ms_timeout)
|
||||
{
|
||||
ssize_t rc;
|
||||
if (one_way->u.shm.rb == NULL) {
|
||||
return -ENOTCONN;
|
||||
}
|
||||
return qb_rb_chunk_peek(one_way->u.shm.rb, data_out, ms_timeout);
|
||||
rc = qb_rb_chunk_peek(one_way->u.shm.rb, data_out, ms_timeout);
|
||||
if (rc == 0) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -233,6 +238,40 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c)
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t
|
||||
qb_ipcs_shm_rb_open(struct qb_ipcs_connection *c,
|
||||
struct qb_ipc_one_way *ow,
|
||||
const char *rb_name)
|
||||
{
|
||||
int32_t res = 0;
|
||||
|
||||
ow->u.shm.rb = qb_rb_open(rb_name,
|
||||
ow->max_msg_size,
|
||||
QB_RB_FLAG_CREATE |
|
||||
QB_RB_FLAG_SHARED_PROCESS,
|
||||
sizeof(int32_t));
|
||||
if (ow->u.shm.rb == NULL) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "qb_rb_open:%s", rb_name);
|
||||
return res;
|
||||
}
|
||||
res = qb_rb_chown(ow->u.shm.rb, c->auth.uid, c->auth.gid);
|
||||
if (res != 0) {
|
||||
qb_util_perror(LOG_ERR, "qb_rb_chown:%s", rb_name);
|
||||
goto cleanup;
|
||||
}
|
||||
res = qb_rb_chmod(ow->u.shm.rb, c->auth.mode);
|
||||
if (res != 0) {
|
||||
qb_util_perror(LOG_ERR, "qb_rb_chmod:%s", rb_name);
|
||||
goto cleanup;
|
||||
}
|
||||
return res;
|
||||
|
||||
cleanup:
|
||||
qb_rb_close(ow->u.shm.rb);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
qb_ipcs_shm_connect(struct qb_ipcs_service *s,
|
||||
struct qb_ipcs_connection *c,
|
||||
@ -242,66 +281,34 @@ qb_ipcs_shm_connect(struct qb_ipcs_service *s,
|
||||
|
||||
qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid);
|
||||
|
||||
snprintf(r->request, NAME_MAX, "%s-request-%d-%d", s->name, c->pid,
|
||||
c->setup.u.us.sock);
|
||||
snprintf(r->response, NAME_MAX, "%s-response-%d-%d", s->name, c->pid,
|
||||
c->setup.u.us.sock);
|
||||
snprintf(r->event, NAME_MAX, "%s-event-%d-%d", s->name, c->pid,
|
||||
c->setup.u.us.sock);
|
||||
snprintf(r->request, NAME_MAX, "%s-request-%s",
|
||||
s->name, c->description);
|
||||
snprintf(r->response, NAME_MAX, "%s-response-%s",
|
||||
s->name, c->description);
|
||||
snprintf(r->event, NAME_MAX, "%s-event-%s",
|
||||
s->name, c->description);
|
||||
|
||||
c->request.u.shm.rb = qb_rb_open(r->request,
|
||||
c->request.max_msg_size,
|
||||
QB_RB_FLAG_CREATE |
|
||||
QB_RB_FLAG_SHARED_PROCESS,
|
||||
sizeof(int32_t));
|
||||
if (c->request.u.shm.rb == NULL) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "qb_rb_open:REQUEST");
|
||||
goto cleanup;
|
||||
}
|
||||
res = qb_rb_chown(c->request.u.shm.rb, c->euid, c->egid);
|
||||
res = qb_ipcs_shm_rb_open(c, &c->request,
|
||||
r->request);
|
||||
if (res != 0) {
|
||||
qb_util_perror(LOG_ERR, "qb_rb_chown:REQUEST");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
c->response.u.shm.rb = qb_rb_open(r->response,
|
||||
c->response.max_msg_size,
|
||||
QB_RB_FLAG_CREATE |
|
||||
QB_RB_FLAG_SHARED_PROCESS, 0);
|
||||
if (c->response.u.shm.rb == NULL) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "qb_rb_open:RESPONSE");
|
||||
goto cleanup_request;
|
||||
}
|
||||
res = qb_rb_chown(c->response.u.shm.rb, c->euid, c->egid);
|
||||
res = qb_ipcs_shm_rb_open(c, &c->response,
|
||||
r->response);
|
||||
if (res != 0) {
|
||||
qb_util_perror(LOG_ERR, "qb_rb_chown:RESPONSE");
|
||||
goto cleanup_request;
|
||||
}
|
||||
|
||||
c->event.u.shm.rb = qb_rb_open(r->event,
|
||||
c->event.max_msg_size,
|
||||
QB_RB_FLAG_CREATE |
|
||||
QB_RB_FLAG_SHARED_PROCESS, 0);
|
||||
|
||||
if (c->event.u.shm.rb == NULL) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "qb_rb_open:EVENT");
|
||||
res = qb_ipcs_shm_rb_open(c, &c->event,
|
||||
r->event);
|
||||
if (res != 0) {
|
||||
goto cleanup_request_response;
|
||||
}
|
||||
res = qb_rb_chown(c->event.u.shm.rb, c->euid, c->egid);
|
||||
if (res != 0) {
|
||||
qb_util_perror(LOG_ERR, "qb_rb_chown:EVENT");
|
||||
goto cleanup_all;
|
||||
}
|
||||
|
||||
r->hdr.error = 0;
|
||||
return 0;
|
||||
|
||||
cleanup_all:
|
||||
qb_rb_close(c->event.u.shm.rb);
|
||||
|
||||
cleanup_request_response:
|
||||
qb_rb_close(c->request.u.shm.rb);
|
||||
|
||||
|
||||
@ -1,394 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* Author: Angus Salkeld <asalkeld@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "os_base.h"
|
||||
|
||||
#ifdef HAVE_SYS_IPC_H
|
||||
#include <sys/ipc.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MSG_H
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qbloop.h>
|
||||
#include "ipc_int.h"
|
||||
#include "util_int.h"
|
||||
|
||||
#ifndef MSGMAX
|
||||
#define MSGMAX 8192
|
||||
#endif
|
||||
|
||||
#define MY_DATA_SIZE 8000
|
||||
struct my_msgbuf {
|
||||
int32_t id __attribute__ ((aligned(8)));
|
||||
char data[MY_DATA_SIZE] __attribute__ ((aligned(8)));
|
||||
} __attribute__ ((aligned(8)));
|
||||
|
||||
/*
|
||||
* utility functions
|
||||
* --------------------------------------------------------
|
||||
*/
|
||||
static int32_t
|
||||
sysv_mq_unnamed_create(struct qb_ipcs_connection *c,
|
||||
struct qb_ipc_one_way *queue)
|
||||
{
|
||||
struct msqid_ds info;
|
||||
int32_t res = 0;
|
||||
|
||||
retry_creating_the_q:
|
||||
queue->u.smq.key = random();
|
||||
queue->u.smq.q =
|
||||
msgget(queue->u.smq.key,
|
||||
IPC_CREAT | IPC_EXCL | IPC_NOWAIT | S_IWUSR | S_IRUSR);
|
||||
if (queue->u.smq.q == -1 && errno == EEXIST) {
|
||||
goto retry_creating_the_q;
|
||||
} else if (queue->u.smq.q == -1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* change the queue size and change the ownership to that of
|
||||
* the client so they can access it.
|
||||
*/
|
||||
res = msgctl(queue->u.smq.q, IPC_STAT, &info);
|
||||
if (res != 0) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "error getting sysv-mq info");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (info.msg_perm.uid != 0) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"not enough privileges to increase msg_qbytes");
|
||||
return res;
|
||||
}
|
||||
info.msg_qbytes = 2 * queue->max_msg_size;
|
||||
info.msg_perm.uid = c->euid;
|
||||
info.msg_perm.gid = c->egid;
|
||||
|
||||
res = msgctl(queue->u.smq.q, IPC_SET, &info);
|
||||
if (res != 0) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR,
|
||||
"error modifying the SYSV message queue");
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
sysv_split_and_send(int32_t q, const void *msg_ptr,
|
||||
size_t msg_len, int32_t last_chunk)
|
||||
{
|
||||
int32_t res;
|
||||
int32_t sent = 0;
|
||||
#ifdef PACK_MESSAGES
|
||||
char *progress = (char *)msg_ptr;
|
||||
struct my_msgbuf buf;
|
||||
size_t to_send_now; /* to send in this message */
|
||||
size_t to_send_next; /* to send in next message */
|
||||
|
||||
do {
|
||||
to_send_now = QB_MIN(msg_len - sent, MY_DATA_SIZE);
|
||||
to_send_next = msg_len - (sent + to_send_now);
|
||||
/* receiver used the ID to check to see if there
|
||||
* is more to receive for this message.
|
||||
*/
|
||||
if (last_chunk) {
|
||||
buf.id = to_send_next + 1;
|
||||
} else {
|
||||
buf.id = to_send_next + 1 + msg_len;
|
||||
}
|
||||
memcpy(buf.data, progress, to_send_now);
|
||||
res = msgsnd(q, &buf, to_send_now, IPC_NOWAIT);
|
||||
if (res == 0) {
|
||||
sent += to_send_now;
|
||||
progress += to_send_now;
|
||||
} else {
|
||||
goto return_status;
|
||||
}
|
||||
|
||||
} while (sent < msg_len);
|
||||
|
||||
return_status:
|
||||
#else
|
||||
res = msgsnd(q, msg_ptr, msg_len, IPC_NOWAIT);
|
||||
sent = msg_len;
|
||||
#endif
|
||||
if (res == -1) {
|
||||
return -errno;
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
/*
|
||||
* client functions
|
||||
* --------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
qb_ipc_smq_send(struct qb_ipc_one_way *one_way,
|
||||
const void *msg_ptr, size_t msg_len)
|
||||
{
|
||||
return sysv_split_and_send(one_way->u.smq.q, msg_ptr, msg_len, QB_TRUE);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qb_ipc_smq_sendv(struct qb_ipc_one_way *one_way,
|
||||
const struct iovec *iov, size_t iov_len)
|
||||
{
|
||||
int32_t res;
|
||||
int32_t sent = 0;
|
||||
struct my_msgbuf buf;
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < iov_len; i++) {
|
||||
if (iov[i].iov_len <= MY_DATA_SIZE) {
|
||||
if (i == iov_len - 1) {
|
||||
buf.id = 1;
|
||||
} else {
|
||||
buf.id = i + iov[i].iov_len;
|
||||
}
|
||||
memcpy(buf.data, iov[i].iov_base, iov[i].iov_len);
|
||||
res = msgsnd(one_way->u.smq.q,
|
||||
&buf, iov[i].iov_len,
|
||||
IPC_NOWAIT);
|
||||
if (res == 0) {
|
||||
res = iov[i].iov_len;
|
||||
} else {
|
||||
res = -errno;
|
||||
}
|
||||
} else {
|
||||
res = sysv_split_and_send(one_way->u.smq.q,
|
||||
iov[i].iov_base,
|
||||
iov[i].iov_len,
|
||||
(i == iov_len - 1));
|
||||
}
|
||||
if (res > 0) {
|
||||
sent += res;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qb_ipc_smq_recv(struct qb_ipc_one_way *one_way,
|
||||
void *msg_ptr, size_t msg_len, int32_t ms_timeout)
|
||||
{
|
||||
ssize_t res;
|
||||
ssize_t received = 0;
|
||||
#ifdef PACK_MESSAGES
|
||||
char *progress = (char *)msg_ptr;
|
||||
struct my_msgbuf buf;
|
||||
|
||||
do {
|
||||
try_again:
|
||||
res = msgrcv(one_way->u.smq.q, &buf,
|
||||
MY_DATA_SIZE, 0, IPC_NOWAIT);
|
||||
|
||||
if (res == -1 && errno == ENOMSG) {
|
||||
goto try_again;
|
||||
}
|
||||
//printf("res:%zd, ID:%d\n", res, buf.id);
|
||||
if (res == -1) {
|
||||
goto return_status;
|
||||
}
|
||||
memcpy(progress, buf.data, res);
|
||||
received += res;
|
||||
progress += res;
|
||||
} while (buf.id > 1);
|
||||
return_status:
|
||||
#else
|
||||
res = msgrcv(one_way->u.smq.q, msg_ptr, msg_len, 0, IPC_NOWAIT);
|
||||
received = res;
|
||||
#endif
|
||||
if (res == -1 && errno == ENOMSG) {
|
||||
/* just to be consistent with other IPC types.
|
||||
*/
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (res == -1) {
|
||||
perror(__func__);
|
||||
return -errno;
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
static void
|
||||
qb_ipcc_smq_disconnect(struct qb_ipcc_connection *c)
|
||||
{
|
||||
struct qb_ipc_request_header hdr;
|
||||
|
||||
qb_util_log(LOG_TRACE, "%s()", __func__);
|
||||
|
||||
hdr.id = QB_IPC_MSG_DISCONNECT;
|
||||
hdr.size = sizeof(hdr);
|
||||
(void)sysv_split_and_send(c->request.u.smq.q,
|
||||
(const char *)&hdr, hdr.size, QB_TRUE);
|
||||
|
||||
msgctl(c->event.u.smq.q, IPC_RMID, NULL);
|
||||
msgctl(c->response.u.smq.q, IPC_RMID, NULL);
|
||||
msgctl(c->request.u.smq.q, IPC_RMID, NULL);
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_ipcc_smq_connect(struct qb_ipcc_connection *c,
|
||||
struct qb_ipc_connection_response *response)
|
||||
{
|
||||
int32_t res = 0;
|
||||
|
||||
c->funcs.send = qb_ipc_smq_send;
|
||||
c->funcs.sendv = qb_ipc_smq_sendv;
|
||||
c->funcs.recv = qb_ipc_smq_recv;
|
||||
c->funcs.fc_get = NULL;
|
||||
c->funcs.disconnect = qb_ipcc_smq_disconnect;
|
||||
c->needs_sock_for_poll = QB_TRUE;
|
||||
|
||||
if (strlen(c->name) > (NAME_MAX - 20)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&c->request.u.smq.key, response->request, sizeof(uint32_t));
|
||||
c->request.u.smq.q = msgget(c->request.u.smq.key, IPC_NOWAIT);
|
||||
if (c->request.u.smq.q == -1) {
|
||||
res = -errno;
|
||||
perror("msgget:REQUEST");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(&c->response.u.smq.key, response->response, sizeof(uint32_t));
|
||||
c->response.u.smq.q = msgget(c->response.u.smq.key, IPC_NOWAIT);
|
||||
if (c->response.u.smq.q == -1) {
|
||||
res = -errno;
|
||||
perror("msgget:RESPONSE");
|
||||
goto cleanup_request;
|
||||
}
|
||||
|
||||
memcpy(&c->event.u.smq.key, response->event, sizeof(uint32_t));
|
||||
c->event.u.smq.q = msgget(c->event.u.smq.key, IPC_NOWAIT);
|
||||
if (c->event.u.smq.q == -1) {
|
||||
res = -errno;
|
||||
perror("msgget:EVENT");
|
||||
goto cleanup_request_response;
|
||||
}
|
||||
return 0;
|
||||
|
||||
cleanup_request_response:
|
||||
msgctl(c->response.u.smq.q, IPC_RMID, NULL);
|
||||
cleanup_request:
|
||||
msgctl(c->request.u.smq.q, IPC_RMID, NULL);
|
||||
cleanup:
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* service functions
|
||||
* --------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
qb_ipcs_smq_disconnect(struct qb_ipcs_connection *c)
|
||||
{
|
||||
struct qb_ipc_response_header msg;
|
||||
|
||||
if (c->setup.u.us.sock != -1) {
|
||||
msg.id = QB_IPC_MSG_DISCONNECT;
|
||||
msg.size = sizeof(msg);
|
||||
msg.error = 0;
|
||||
|
||||
(void)qb_ipc_smq_send(&c->event, &msg, msg.size);
|
||||
} else {
|
||||
msgctl(c->event.u.smq.q, IPC_RMID, NULL);
|
||||
msgctl(c->response.u.smq.q, IPC_RMID, NULL);
|
||||
msgctl(c->request.u.smq.q, IPC_RMID, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t
|
||||
qb_ipcs_smq_connect(struct qb_ipcs_service *s,
|
||||
struct qb_ipcs_connection *c,
|
||||
struct qb_ipc_connection_response *r)
|
||||
{
|
||||
int32_t res = 0;
|
||||
|
||||
res = sysv_mq_unnamed_create(c, &c->request);
|
||||
if (res < 0) {
|
||||
res = -errno;
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(r->request, &c->request.u.smq.key, sizeof(int32_t));
|
||||
|
||||
res = sysv_mq_unnamed_create(c, &c->response);
|
||||
if (res < 0) {
|
||||
res = -errno;
|
||||
goto cleanup_request;
|
||||
}
|
||||
memcpy(r->response, &c->response.u.smq.key, sizeof(int32_t));
|
||||
|
||||
res = sysv_mq_unnamed_create(c, &c->event);
|
||||
if (res < 0) {
|
||||
res = -errno;
|
||||
goto cleanup_request_response;
|
||||
}
|
||||
memcpy(r->event, &c->event.u.smq.key, sizeof(int32_t));
|
||||
|
||||
r->hdr.error = 0;
|
||||
return 0;
|
||||
|
||||
cleanup_request_response:
|
||||
msgctl(c->response.u.smq.q, IPC_RMID, NULL);
|
||||
cleanup_request:
|
||||
msgctl(c->request.u.smq.q, IPC_RMID, NULL);
|
||||
|
||||
cleanup:
|
||||
r->hdr.error = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qb_ipc_smq_q_len_get(struct qb_ipc_one_way *one_way)
|
||||
{
|
||||
struct msqid_ds info;
|
||||
int32_t res = msgctl(one_way->u.smq.q, IPC_STAT, &info);
|
||||
if (res == 0) {
|
||||
return info.msg_qnum;
|
||||
}
|
||||
return -errno;
|
||||
}
|
||||
|
||||
void
|
||||
qb_ipcs_smq_init(struct qb_ipcs_service *s)
|
||||
{
|
||||
s->funcs.connect = qb_ipcs_smq_connect;
|
||||
s->funcs.disconnect = qb_ipcs_smq_disconnect;
|
||||
|
||||
s->funcs.send = qb_ipc_smq_send;
|
||||
s->funcs.sendv = qb_ipc_smq_sendv;
|
||||
s->funcs.recv = qb_ipc_smq_recv;
|
||||
s->funcs.peek = NULL;
|
||||
s->funcs.reclaim = NULL;
|
||||
|
||||
s->funcs.fc_set = NULL;
|
||||
s->funcs.q_len_get = qb_ipc_smq_q_len_get;
|
||||
|
||||
s->needs_sock_for_poll = QB_TRUE;
|
||||
}
|
||||
452
lib/ipc_us.c
452
lib/ipc_us.c
@ -48,16 +48,22 @@
|
||||
#define UNIX_PATH_MAX 108
|
||||
#endif /* UNIX_PATH_MAX */
|
||||
|
||||
#if defined(QB_LINUX) || defined(QB_SOLARIS)
|
||||
#define QB_SUN_LEN(a) sizeof(*(a))
|
||||
/*
|
||||
* SUN_LEN() does a strlen() on sun_path, but if you are trying to use the
|
||||
* "Linux abstract namespace" (you have to set sun_path[0] == '\0') then
|
||||
* the strlen() doesn't work.
|
||||
*/
|
||||
#if defined(SUN_LEN)
|
||||
#define QB_SUN_LEN(a) ((a)->sun_path[0] == '\0') ? sizeof(*(a)) : SUN_LEN(a)
|
||||
#else
|
||||
#define QB_SUN_LEN(a) SUN_LEN(a)
|
||||
#define QB_SUN_LEN(a) sizeof(*(a))
|
||||
#endif
|
||||
|
||||
struct ipc_us_control {
|
||||
int32_t sent;
|
||||
int32_t flow_control;
|
||||
};
|
||||
#define SHM_CONTROL_SIZE (3 * sizeof(struct ipc_us_control))
|
||||
|
||||
struct ipc_auth_ugp {
|
||||
uid_t uid;
|
||||
@ -85,33 +91,21 @@ ssize_t
|
||||
qb_ipc_us_send(struct qb_ipc_one_way *one_way, const void *msg, size_t len)
|
||||
{
|
||||
int32_t result;
|
||||
struct msghdr msg_send;
|
||||
struct iovec iov_send;
|
||||
char *rbuf = (char *)msg;
|
||||
int32_t processed = 0;
|
||||
struct ipc_us_control *ctl = NULL;
|
||||
|
||||
msg_send.msg_iov = &iov_send;
|
||||
msg_send.msg_iovlen = 1;
|
||||
msg_send.msg_name = 0;
|
||||
msg_send.msg_namelen = 0;
|
||||
|
||||
#if !defined(QB_SOLARIS)
|
||||
msg_send.msg_control = 0;
|
||||
msg_send.msg_controllen = 0;
|
||||
msg_send.msg_flags = 0;
|
||||
#else
|
||||
msg_send.msg_accrights = NULL;
|
||||
msg_send.msg_accrightslen = 0;
|
||||
#endif
|
||||
char *rbuf = (char *)msg;
|
||||
|
||||
retry_send:
|
||||
iov_send.iov_base = &rbuf[processed];
|
||||
iov_send.iov_len = len - processed;
|
||||
result = send(one_way->u.us.sock,
|
||||
&rbuf[processed],
|
||||
len - processed,
|
||||
MSG_NOSIGNAL);
|
||||
|
||||
result = sendmsg(one_way->u.us.sock, &msg_send, MSG_NOSIGNAL);
|
||||
if (result == -1) {
|
||||
return -errno;
|
||||
if (errno == EAGAIN && processed > 0) {
|
||||
goto retry_send;
|
||||
} else {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
processed += result;
|
||||
@ -119,6 +113,7 @@ retry_send:
|
||||
goto retry_send;
|
||||
}
|
||||
if (one_way->type == QB_IPC_SOCKET) {
|
||||
struct ipc_us_control *ctl = NULL;
|
||||
ctl = (struct ipc_us_control *)one_way->u.us.shared_data;
|
||||
if (ctl) {
|
||||
qb_atomic_int_inc(&ctl->sent);
|
||||
@ -132,46 +127,46 @@ qb_ipc_us_sendv(struct qb_ipc_one_way *one_way, const struct iovec *iov,
|
||||
size_t iov_len)
|
||||
{
|
||||
int32_t result;
|
||||
struct msghdr msg_send;
|
||||
int32_t processed = 0;
|
||||
size_t len = 0;
|
||||
int32_t i;
|
||||
struct ipc_us_control *ctl = NULL;
|
||||
|
||||
for (i = 0; i < iov_len; i++) {
|
||||
len += iov[i].iov_len;
|
||||
}
|
||||
msg_send.msg_iov = (struct iovec *)iov;
|
||||
msg_send.msg_iovlen = iov_len;
|
||||
msg_send.msg_name = 0;
|
||||
msg_send.msg_namelen = 0;
|
||||
|
||||
#if !defined(QB_SOLARIS)
|
||||
msg_send.msg_control = 0;
|
||||
msg_send.msg_controllen = 0;
|
||||
msg_send.msg_flags = 0;
|
||||
#else
|
||||
msg_send.msg_accrights = NULL;
|
||||
msg_send.msg_accrightslen = 0;
|
||||
#endif
|
||||
int32_t total_processed = 0;
|
||||
int32_t iov_p = 0;
|
||||
char *rbuf = (char *)iov[iov_p].iov_base;
|
||||
|
||||
retry_send:
|
||||
result = sendmsg(one_way->u.us.sock, &msg_send, MSG_NOSIGNAL);
|
||||
result = send(one_way->u.us.sock,
|
||||
&rbuf[processed],
|
||||
iov[iov_p].iov_len - processed,
|
||||
MSG_NOSIGNAL);
|
||||
|
||||
if (result == -1) {
|
||||
return -errno;
|
||||
if (errno == EAGAIN &&
|
||||
(processed > 0 || iov_p > 0)) {
|
||||
goto retry_send;
|
||||
} else {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
processed += result;
|
||||
if (processed != len) {
|
||||
if (processed == iov[iov_p].iov_len) {
|
||||
iov_p++;
|
||||
total_processed += processed;
|
||||
if (iov_p < iov_len) {
|
||||
processed = 0;
|
||||
rbuf = (char *)iov[iov_p].iov_base;
|
||||
goto retry_send;
|
||||
}
|
||||
} else {
|
||||
goto retry_send;
|
||||
}
|
||||
if (one_way->type == QB_IPC_SOCKET) {
|
||||
struct ipc_us_control *ctl;
|
||||
ctl = (struct ipc_us_control *)one_way->u.us.shared_data;
|
||||
if (ctl) {
|
||||
qb_atomic_int_inc(&ctl->sent);
|
||||
}
|
||||
}
|
||||
return processed;
|
||||
return total_processed;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@ -191,14 +186,11 @@ retry_recv:
|
||||
if (result == -1) {
|
||||
return -errno;
|
||||
}
|
||||
#if defined(QB_SOLARIS) || defined(QB_BSD) || defined(QB_DARWIN)
|
||||
/* On many OS poll never return POLLHUP or POLLERR.
|
||||
* EOF is detected when recvmsg return 0.
|
||||
*/
|
||||
if (result == 0) {
|
||||
return -errno; //ENOTCONN
|
||||
qb_util_log(LOG_DEBUG,
|
||||
"recv(fd %d) got 0 bytes assuming ENOTCONN", s);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
|
||||
processed += result;
|
||||
if (processed != len) {
|
||||
@ -210,13 +202,29 @@ retry_recv:
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_ipc_us_recv_ready(struct qb_ipc_one_way * one_way, int32_t ms_timeout)
|
||||
qb_ipc_us_sock_error_is_disconnected(int err)
|
||||
{
|
||||
if (err == -EAGAIN ||
|
||||
err == -ETIMEDOUT ||
|
||||
err == -EINTR ||
|
||||
#ifdef EWOULDBLOCK
|
||||
err == -EWOULDBLOCK ||
|
||||
#endif
|
||||
err == -EINVAL) {
|
||||
return QB_FALSE;
|
||||
}
|
||||
return QB_TRUE;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_ipc_us_ready(struct qb_ipc_one_way * one_way,
|
||||
int32_t ms_timeout, int32_t events)
|
||||
{
|
||||
struct pollfd ufds;
|
||||
int32_t poll_events;
|
||||
|
||||
ufds.fd = one_way->u.us.sock;
|
||||
ufds.events = POLLIN;
|
||||
ufds.events = events;
|
||||
ufds.revents = 0;
|
||||
|
||||
poll_events = poll(&ufds, 1, ms_timeout);
|
||||
@ -224,7 +232,14 @@ qb_ipc_us_recv_ready(struct qb_ipc_one_way * one_way, int32_t ms_timeout)
|
||||
return -EAGAIN;
|
||||
} else if (poll_events == -1) {
|
||||
return -errno;
|
||||
} else if (poll_events == 1 && (ufds.revents & (POLLERR | POLLHUP))) {
|
||||
} else if (poll_events == 1 && (ufds.revents & POLLERR)) {
|
||||
qb_util_log(LOG_DEBUG, "poll(fd %d) got POLLERR", one_way->u.us.sock);
|
||||
return -ENOTCONN;
|
||||
} else if (poll_events == 1 && (ufds.revents & POLLHUP)) {
|
||||
qb_util_log(LOG_DEBUG, "poll(fd %d) got POLLHUP", one_way->u.us.sock);
|
||||
return -ENOTCONN;
|
||||
} else if (poll_events == 1 && (ufds.revents & POLLNVAL)) {
|
||||
qb_util_log(LOG_DEBUG, "poll(fd %d) got POLLNVAL", one_way->u.us.sock);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
return 0;
|
||||
@ -241,27 +256,38 @@ qb_ipc_us_recv(struct qb_ipc_one_way * one_way,
|
||||
int32_t processed = 0;
|
||||
int32_t to_recv = len;
|
||||
char *data = msg;
|
||||
struct ipc_us_control *ctl = NULL;
|
||||
|
||||
retry_recv:
|
||||
result = recv(one_way->u.us.sock, &data[processed], to_recv, MSG_NOSIGNAL | MSG_WAITALL);
|
||||
if (timeout == -1) {
|
||||
if (result == -1 && errno == EAGAIN) {
|
||||
result = recv(one_way->u.us.sock, &data[processed], to_recv,
|
||||
MSG_NOSIGNAL | MSG_WAITALL);
|
||||
|
||||
if (result == -1) {
|
||||
if (errno == EAGAIN &&
|
||||
(processed > 0 || timeout == -1)) {
|
||||
goto retry_recv;
|
||||
} else if (errno == ECONNRESET || errno == EPIPE) {
|
||||
qb_util_perror(LOG_DEBUG,
|
||||
"recv(fd %d) converting to ENOTCONN",
|
||||
one_way->u.us.sock);
|
||||
return -ENOTCONN;
|
||||
} else {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
qb_util_log(LOG_DEBUG,
|
||||
"recv(fd %d) got 0 bytes assuming ENOTCONN",
|
||||
one_way->u.us.sock);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
if (result == -1) {
|
||||
return -errno;
|
||||
}
|
||||
processed += result;
|
||||
to_recv -= result;
|
||||
if (processed != len) {
|
||||
goto retry_recv;
|
||||
}
|
||||
if (one_way->type == QB_IPC_SOCKET) {
|
||||
struct ipc_us_control *ctl = NULL;
|
||||
ctl = (struct ipc_us_control *)one_way->u.us.shared_data;
|
||||
if (ctl) {
|
||||
(void)qb_atomic_int_dec_and_test(&ctl->sent);
|
||||
@ -271,34 +297,53 @@ retry_recv:
|
||||
}
|
||||
|
||||
/*
|
||||
* recv a message of unknow size.
|
||||
* (could use MSG_PEEK here)
|
||||
* recv a message of unknown size.
|
||||
*/
|
||||
static ssize_t
|
||||
qb_ipc_us_recv_at_most(struct qb_ipc_one_way * one_way,
|
||||
void *msg, size_t len, int32_t timeout)
|
||||
{
|
||||
int32_t result;
|
||||
int32_t processed = 0;
|
||||
int32_t to_recv = sizeof(struct qb_ipc_request_header);
|
||||
char *data = msg;
|
||||
struct ipc_us_control *ctl = NULL;
|
||||
struct qb_ipc_request_header *hdr = NULL;
|
||||
|
||||
retry_recv:
|
||||
result = recv(one_way->u.us.sock, msg, len, MSG_NOSIGNAL | MSG_WAITALL);
|
||||
if (timeout == -1) {
|
||||
if (result == -1 && errno == EAGAIN) {
|
||||
result = recv(one_way->u.us.sock, &data[processed], to_recv,
|
||||
MSG_NOSIGNAL | MSG_WAITALL);
|
||||
if (result == -1) {
|
||||
if (errno == EAGAIN &&
|
||||
(processed > 0 || timeout == -1)) {
|
||||
goto retry_recv;
|
||||
} else {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
if (result == 0) {
|
||||
} else if (result == 0) {
|
||||
qb_util_log(LOG_DEBUG,
|
||||
"recv(fd %d) got 0 bytes assuming ENOTCONN",
|
||||
one_way->u.us.sock);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
if (result == -1) {
|
||||
return -errno;
|
||||
|
||||
processed += result;
|
||||
if (processed >= sizeof(struct qb_ipc_request_header) && hdr == NULL) {
|
||||
hdr = (struct qb_ipc_request_header*)msg;
|
||||
}
|
||||
if (hdr) {
|
||||
to_recv = hdr->size - processed;
|
||||
} else {
|
||||
to_recv = len - processed;
|
||||
}
|
||||
if (to_recv > 0) {
|
||||
goto retry_recv;
|
||||
}
|
||||
ctl = (struct ipc_us_control *)one_way->u.us.shared_data;
|
||||
if (ctl) {
|
||||
(void)qb_atomic_int_dec_and_test(&ctl->sent);
|
||||
}
|
||||
return result;
|
||||
return processed;
|
||||
}
|
||||
|
||||
|
||||
@ -309,11 +354,7 @@ qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_pt)
|
||||
struct sockaddr_un address;
|
||||
int32_t res = 0;
|
||||
|
||||
#if defined(QB_SOLARIS)
|
||||
request_fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
#else
|
||||
request_fd = socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||
#endif
|
||||
if (request_fd == -1) {
|
||||
return -errno;
|
||||
}
|
||||
@ -327,11 +368,11 @@ qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_pt)
|
||||
|
||||
memset(&address, 0, sizeof(struct sockaddr_un));
|
||||
address.sun_family = AF_UNIX;
|
||||
#if defined(QB_BSD) || defined(QB_DARWIN)
|
||||
address.sun_len = SUN_LEN(&address);
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||
address.sun_len = QB_SUN_LEN(&address);
|
||||
#endif
|
||||
|
||||
#if defined(QB_LINUX)
|
||||
#if defined(QB_LINUX) || defined(QB_CYGWIN)
|
||||
snprintf(address.sun_path + 1, UNIX_PATH_MAX - 1, "%s", socket_name);
|
||||
#else
|
||||
snprintf(address.sun_path, UNIX_PATH_MAX, "%s/%s", SOCKETDIR,
|
||||
@ -366,12 +407,21 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
|
||||
{
|
||||
int32_t res;
|
||||
struct qb_ipc_connection_request request;
|
||||
#ifdef QB_LINUX
|
||||
int off = 0;
|
||||
int on = 1;
|
||||
#endif
|
||||
|
||||
res = qb_ipcc_us_sock_connect(c->name, &c->setup.u.us.sock);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef QB_LINUX
|
||||
setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
|
||||
#endif
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.hdr.id = QB_IPC_MSG_AUTHENTICATE;
|
||||
request.hdr.size = sizeof(request);
|
||||
request.max_msg_size = c->setup.max_msg_size;
|
||||
@ -381,6 +431,10 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef QB_LINUX
|
||||
setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &off, sizeof(off));
|
||||
#endif
|
||||
|
||||
res =
|
||||
qb_ipc_us_recv(&c->setup, r,
|
||||
sizeof(struct qb_ipc_connection_response), -1);
|
||||
@ -397,7 +451,7 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
|
||||
static void
|
||||
qb_ipcc_us_disconnect(struct qb_ipcc_connection *c)
|
||||
{
|
||||
munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control));
|
||||
munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE);
|
||||
unlink(c->request.u.us.shared_file_name);
|
||||
close(c->request.u.us.sock);
|
||||
close(c->event.u.us.sock);
|
||||
@ -411,7 +465,7 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c,
|
||||
struct qb_ipc_event_connection_request request;
|
||||
char path[PATH_MAX];
|
||||
int32_t fd_hdr;
|
||||
struct ipc_us_control *ctl;
|
||||
char * shm_ptr;
|
||||
|
||||
c->needs_sock_for_poll = QB_FALSE;
|
||||
c->funcs.send = qb_ipc_us_send;
|
||||
@ -425,27 +479,24 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c,
|
||||
c->setup.u.us.sock = -1;
|
||||
|
||||
fd_hdr = qb_sys_mmap_file_open(path, r->request,
|
||||
sizeof(struct ipc_us_control), O_RDWR);
|
||||
SHM_CONTROL_SIZE, O_RDWR);
|
||||
if (fd_hdr < 0) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "couldn't open file for mmap");
|
||||
return res;
|
||||
}
|
||||
(void)strlcpy(c->request.u.us.shared_file_name, r->request, NAME_MAX);
|
||||
c->request.u.us.shared_data = mmap(0,
|
||||
sizeof(struct ipc_us_control),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
fd_hdr, 0);
|
||||
shm_ptr = mmap(0, SHM_CONTROL_SIZE,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, fd_hdr, 0);
|
||||
|
||||
if (c->request.u.us.shared_data == MAP_FAILED) {
|
||||
if (shm_ptr == MAP_FAILED) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "couldn't create mmap for header");
|
||||
goto cleanup_hdr;
|
||||
}
|
||||
|
||||
ctl = (struct ipc_us_control *)c->request.u.us.shared_data;
|
||||
ctl->sent = 0;
|
||||
ctl->flow_control = 0;
|
||||
c->request.u.us.shared_data = shm_ptr;
|
||||
c->response.u.us.shared_data = shm_ptr + sizeof(struct ipc_us_control);
|
||||
c->event.u.us.shared_data = shm_ptr + (2 * sizeof(struct ipc_us_control));
|
||||
|
||||
close(fd_hdr);
|
||||
|
||||
@ -454,13 +505,14 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c,
|
||||
goto cleanup_hdr;
|
||||
}
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.hdr.id = QB_IPC_MSG_NEW_EVENT_SOCK;
|
||||
request.hdr.size = sizeof(request);
|
||||
request.connection = r->connection;
|
||||
res = qb_ipc_us_send(&c->event, &request, request.hdr.size);
|
||||
if (res < 0) {
|
||||
qb_ipcc_us_sock_close(c->event.u.us.sock);
|
||||
return res;
|
||||
goto cleanup_hdr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -468,7 +520,7 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c,
|
||||
cleanup_hdr:
|
||||
close(fd_hdr);
|
||||
unlink(r->request);
|
||||
munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control));
|
||||
munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -486,11 +538,7 @@ qb_ipcs_us_publish(struct qb_ipcs_service * s)
|
||||
/*
|
||||
* Create socket for IPC clients, name socket, listen for connections
|
||||
*/
|
||||
#if defined(QB_SOLARIS)
|
||||
s->server_sock = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
#else
|
||||
s->server_sock = socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||
#endif
|
||||
if (s->server_sock == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "Cannot create server socket");
|
||||
@ -509,7 +557,7 @@ qb_ipcs_us_publish(struct qb_ipcs_service * s)
|
||||
#endif
|
||||
|
||||
qb_util_log(LOG_INFO, "server name: %s", s->name);
|
||||
#if defined(QB_LINUX)
|
||||
#if defined(QB_LINUX) || defined(QB_CYGWIN)
|
||||
snprintf(un_addr.sun_path + 1, UNIX_PATH_MAX - 1, "%s", s->name);
|
||||
#else
|
||||
{
|
||||
@ -541,7 +589,7 @@ qb_ipcs_us_publish(struct qb_ipcs_service * s)
|
||||
* Allow everyone to write to the socket since the IPC layer handles
|
||||
* security automatically
|
||||
*/
|
||||
#if !defined(QB_LINUX)
|
||||
#if !defined(QB_LINUX) && !defined(QB_CYGWIN)
|
||||
res = chmod(un_addr.sun_path, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
#endif
|
||||
if (listen(s->server_sock, SERVER_BACKLOG) == -1) {
|
||||
@ -585,7 +633,7 @@ handle_new_connection(struct qb_ipcs_service *s,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
c->receive_buf = malloc(req->max_msg_size);
|
||||
c->receive_buf = calloc(1, req->max_msg_size);
|
||||
if (c->receive_buf == NULL) {
|
||||
free(c);
|
||||
qb_ipcc_us_sock_close(sock);
|
||||
@ -596,9 +644,13 @@ handle_new_connection(struct qb_ipcs_service *s,
|
||||
c->response.max_msg_size = req->max_msg_size;
|
||||
c->event.max_msg_size = req->max_msg_size;
|
||||
c->pid = ugp->pid;
|
||||
c->euid = ugp->uid;
|
||||
c->egid = ugp->gid;
|
||||
c->auth.uid = c->euid = ugp->uid;
|
||||
c->auth.gid = c->egid = ugp->gid;
|
||||
c->auth.mode = 0600;
|
||||
c->stats.client_pid = ugp->pid;
|
||||
snprintf(c->description, CONNECTION_DESCRIPTION,
|
||||
"%d-%d-%d", s->pid, ugp->pid,
|
||||
c->setup.u.us.sock);
|
||||
|
||||
if (auth_result == 0 && c->service->serv_fns.connection_accept) {
|
||||
res = c->service->serv_fns.connection_accept(c,
|
||||
@ -608,7 +660,8 @@ handle_new_connection(struct qb_ipcs_service *s,
|
||||
goto send_response;
|
||||
}
|
||||
|
||||
qb_util_log(LOG_INFO, "IPC credentials authenticated");
|
||||
qb_util_log(LOG_DEBUG, "IPC credentials authenticated (%s)",
|
||||
c->description);
|
||||
|
||||
memset(&response, 0, sizeof(response));
|
||||
if (s->funcs.connect) {
|
||||
@ -630,19 +683,15 @@ handle_new_connection(struct qb_ipcs_service *s,
|
||||
POLLIN | POLLPRI | POLLNVAL,
|
||||
c,
|
||||
qb_ipcs_dispatch_connection_request);
|
||||
if (res < 0) {
|
||||
qb_util_log(LOG_ERR,
|
||||
"Error adding socket to mainloop (%s).",
|
||||
c->description);
|
||||
}
|
||||
}
|
||||
if (s->type == QB_IPC_SOCKET) {
|
||||
c->request.u.us.sock = c->setup.u.us.sock;
|
||||
c->response.u.us.sock = c->setup.u.us.sock;
|
||||
res = s->poll_fns.dispatch_add(s->poll_priority,
|
||||
c->request.u.us.sock,
|
||||
POLLIN | POLLPRI | POLLNVAL,
|
||||
c,
|
||||
qb_ipcs_dispatch_connection_request);
|
||||
if (res < 0) {
|
||||
qb_util_log(LOG_ERR,
|
||||
"Error adding socket to mainloop.");
|
||||
}
|
||||
}
|
||||
|
||||
send_response:
|
||||
@ -662,19 +711,24 @@ send_response:
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
qb_ipcs_connection_ref(c);
|
||||
if (s->serv_fns.connection_created) {
|
||||
s->serv_fns.connection_created(c);
|
||||
if (s->type != QB_IPC_SOCKET) {
|
||||
qb_ipcs_connection_ref(c);
|
||||
if (s->serv_fns.connection_created) {
|
||||
s->serv_fns.connection_created(c);
|
||||
}
|
||||
if (c->state == QB_IPCS_CONNECTION_ACTIVE) {
|
||||
c->state = QB_IPCS_CONNECTION_ESTABLISHED;
|
||||
}
|
||||
qb_ipcs_connection_unref(c);
|
||||
}
|
||||
if (c->state == QB_IPCS_CONNECTION_ACTIVE) {
|
||||
c->state = QB_IPCS_CONNECTION_ESTABLISHED;
|
||||
}
|
||||
qb_ipcs_connection_unref(c);
|
||||
} else {
|
||||
if (res == -EACCES) {
|
||||
qb_util_log(LOG_ERR, "Invalid IPC credentials.");
|
||||
qb_util_log(LOG_ERR, "Invalid IPC credentials (%s).",
|
||||
c->description);
|
||||
} else {
|
||||
qb_util_perror(LOG_ERR, "Error in connection setup");
|
||||
errno = -res;
|
||||
qb_util_perror(LOG_ERR, "Error in connection setup (%s)",
|
||||
c->description);
|
||||
}
|
||||
qb_ipcs_disconnect(c);
|
||||
}
|
||||
@ -688,7 +742,32 @@ handle_connection_new_sock(struct qb_ipcs_service *s, int32_t sock, void *msg)
|
||||
struct qb_ipc_event_connection_request *req = msg;
|
||||
|
||||
c = (struct qb_ipcs_connection *)req->connection;
|
||||
qb_ipcs_connection_ref(c);
|
||||
c->event.u.us.sock = sock;
|
||||
if (c->state == QB_IPCS_CONNECTION_ACTIVE) {
|
||||
c->state = QB_IPCS_CONNECTION_ESTABLISHED;
|
||||
}
|
||||
if (s->serv_fns.connection_created) {
|
||||
s->serv_fns.connection_created(c);
|
||||
}
|
||||
|
||||
if (c->state == QB_IPCS_CONNECTION_ESTABLISHED &&
|
||||
s->type == QB_IPC_SOCKET) {
|
||||
int32_t res;
|
||||
qb_ipcs_connection_ref(c);
|
||||
res = s->poll_fns.dispatch_add(s->poll_priority,
|
||||
c->request.u.us.sock,
|
||||
POLLIN | POLLPRI | POLLNVAL,
|
||||
c,
|
||||
qb_ipcs_dispatch_connection_request);
|
||||
if (res < 0) {
|
||||
qb_util_log(LOG_ERR,
|
||||
"Error adding socket to mainloop (%s).",
|
||||
c->description);
|
||||
}
|
||||
}
|
||||
|
||||
qb_ipcs_connection_unref(c);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
@ -699,28 +778,29 @@ qb_ipcs_uc_recv_and_auth(int32_t sock, void *msg, size_t len,
|
||||
struct msghdr msg_recv;
|
||||
struct iovec iov_recv;
|
||||
|
||||
#ifdef QB_LINUX
|
||||
#ifdef SO_PASSCRED
|
||||
char cmsg_cred[CMSG_SPACE(sizeof(struct ucred))];
|
||||
int off = 0;
|
||||
int on = 1;
|
||||
#endif
|
||||
msg_recv.msg_flags = 0;
|
||||
msg_recv.msg_iov = &iov_recv;
|
||||
msg_recv.msg_iovlen = 1;
|
||||
msg_recv.msg_name = 0;
|
||||
msg_recv.msg_namelen = 0;
|
||||
#ifdef QB_LINUX
|
||||
#ifdef SO_PASSCRED
|
||||
msg_recv.msg_control = (void *)cmsg_cred;
|
||||
msg_recv.msg_controllen = sizeof(cmsg_cred);
|
||||
#endif
|
||||
#ifdef QB_SOLARIS
|
||||
msg_recv.msg_accrights = 0;
|
||||
msg_recv.msg_accrightslen = 0;
|
||||
#else
|
||||
msg_recv.msg_flags = 0;
|
||||
#endif /* QB_SOLARIS */
|
||||
|
||||
iov_recv.iov_base = msg;
|
||||
iov_recv.iov_len = len;
|
||||
#ifdef QB_LINUX
|
||||
#ifdef SO_PASSCRED
|
||||
setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
|
||||
#endif
|
||||
|
||||
@ -776,16 +856,19 @@ qb_ipcs_uc_recv_and_auth(int32_t sock, void *msg, size_t len,
|
||||
*/
|
||||
{
|
||||
struct ucred cred;
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg_recv);
|
||||
assert(cmsg != NULL);
|
||||
if (CMSG_DATA(cmsg)) {
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
res = -EINVAL;
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg_recv); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg_recv, cmsg)) {
|
||||
if (cmsg->cmsg_type != SCM_CREDENTIALS)
|
||||
continue;
|
||||
|
||||
memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred));
|
||||
res = 0;
|
||||
ugp->pid = cred.pid;
|
||||
ugp->uid = cred.uid;
|
||||
ugp->gid = cred.gid;
|
||||
} else {
|
||||
res = -EBADMSG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else /* no credentials */
|
||||
@ -797,7 +880,7 @@ qb_ipcs_uc_recv_and_auth(int32_t sock, void *msg, size_t len,
|
||||
|
||||
cleanup_and_return:
|
||||
|
||||
#ifdef QB_LINUX
|
||||
#ifdef SO_PASSCRED
|
||||
setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &off, sizeof(off));
|
||||
#endif
|
||||
|
||||
@ -815,6 +898,13 @@ qb_ipcs_us_connection_acceptor(int fd, int revent, void *data)
|
||||
struct ipc_auth_ugp ugp;
|
||||
socklen_t addrlen = sizeof(struct sockaddr_un);
|
||||
|
||||
if (revent & (POLLNVAL|POLLHUP|POLLERR)) {
|
||||
/*
|
||||
* handle shutdown more cleanly.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
retry_accept:
|
||||
errno = 0;
|
||||
new_fd = accept(fd, (struct sockaddr *)&un_addr, &addrlen);
|
||||
@ -847,6 +937,13 @@ retry_accept:
|
||||
|
||||
res = qb_ipcs_uc_recv_and_auth(new_fd, &setup_msg, sizeof(setup_msg),
|
||||
&ugp);
|
||||
if (res < 0) {
|
||||
close(new_fd);
|
||||
/* This is an error, but -1 would indicate disconnect
|
||||
* from the poll loop
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (setup_msg.hdr.id == QB_IPC_MSG_AUTHENTICATE) {
|
||||
(void)handle_new_connection(s, res, new_fd, &setup_msg,
|
||||
@ -873,37 +970,60 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s,
|
||||
int32_t fd_hdr;
|
||||
int32_t res = 0;
|
||||
struct ipc_us_control *ctl;
|
||||
char * shm_ptr;
|
||||
|
||||
qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid);
|
||||
qb_util_log(LOG_DEBUG, "connecting to client (%s)",
|
||||
c->description);
|
||||
|
||||
snprintf(r->request, NAME_MAX, "qb-%s-control-%d-%d",
|
||||
s->name, c->pid, c->setup.u.us.sock);
|
||||
snprintf(r->request, NAME_MAX, "qb-%s-control-%s",
|
||||
s->name, c->description);
|
||||
|
||||
fd_hdr = qb_sys_mmap_file_open(path, r->request,
|
||||
sizeof(struct ipc_us_control),
|
||||
SHM_CONTROL_SIZE,
|
||||
O_CREAT | O_TRUNC | O_RDWR);
|
||||
if (fd_hdr < 0) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "couldn't create file for mmap");
|
||||
qb_util_perror(LOG_ERR, "couldn't create file for mmap (%s)",
|
||||
c->description);
|
||||
return res;
|
||||
}
|
||||
(void)strlcpy(r->request, path, PATH_MAX);
|
||||
(void)strlcpy(c->request.u.us.shared_file_name, r->request, NAME_MAX);
|
||||
|
||||
c->request.u.us.shared_data = mmap(0,
|
||||
sizeof(struct ipc_us_control),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
fd_hdr, 0);
|
||||
|
||||
if (c->request.u.us.shared_data == MAP_FAILED) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "couldn't create mmap for header");
|
||||
goto cleanup_hdr;
|
||||
res = chown(r->request, c->auth.uid, c->auth.gid);
|
||||
if (res != 0) {
|
||||
/* ignore res, this is just for the compiler warnings.
|
||||
*/
|
||||
res = 0;
|
||||
}
|
||||
res = chmod(r->request, c->auth.mode);
|
||||
if (res != 0) {
|
||||
/* ignore res, this is just for the compiler warnings.
|
||||
*/
|
||||
res = 0;
|
||||
}
|
||||
|
||||
shm_ptr = mmap(0, SHM_CONTROL_SIZE,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, fd_hdr, 0);
|
||||
|
||||
if (shm_ptr == MAP_FAILED) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "couldn't create mmap for header (%s)",
|
||||
c->description);
|
||||
goto cleanup_hdr;
|
||||
}
|
||||
c->request.u.us.shared_data = shm_ptr;
|
||||
c->response.u.us.shared_data = shm_ptr + sizeof(struct ipc_us_control);
|
||||
c->event.u.us.shared_data = shm_ptr + (2 * sizeof(struct ipc_us_control));
|
||||
|
||||
ctl = (struct ipc_us_control *)c->request.u.us.shared_data;
|
||||
ctl->sent = 0;
|
||||
ctl->flow_control = 0;
|
||||
ctl = (struct ipc_us_control *)c->response.u.us.shared_data;
|
||||
ctl->sent = 0;
|
||||
ctl->flow_control = 0;
|
||||
ctl = (struct ipc_us_control *)c->event.u.us.shared_data;
|
||||
ctl->sent = 0;
|
||||
ctl->flow_control = 0;
|
||||
|
||||
close(fd_hdr);
|
||||
return res;
|
||||
@ -911,7 +1031,7 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s,
|
||||
cleanup_hdr:
|
||||
close(fd_hdr);
|
||||
unlink(r->request);
|
||||
munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control));
|
||||
munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -921,7 +1041,8 @@ qb_ipc_us_fc_set(struct qb_ipc_one_way *one_way, int32_t fc_enable)
|
||||
struct ipc_us_control *ctl =
|
||||
(struct ipc_us_control *)one_way->u.us.shared_data;
|
||||
|
||||
qb_util_log(LOG_TRACE, "setting fc to %d", fc_enable);
|
||||
qb_util_log(LOG_TRACE, "setting fc to %d",
|
||||
fc_enable);
|
||||
qb_atomic_int_set(&ctl->flow_control, fc_enable);
|
||||
}
|
||||
|
||||
@ -942,14 +1063,35 @@ qb_ipc_us_q_len_get(struct qb_ipc_one_way *one_way)
|
||||
return qb_atomic_int_get(&ctl->sent);
|
||||
}
|
||||
|
||||
void
|
||||
qb_ipcs_sockets_disconnect(struct qb_ipcs_connection *c)
|
||||
{
|
||||
int sock = -1;
|
||||
|
||||
qb_enter();
|
||||
if (c->service->needs_sock_for_poll && c->setup.u.us.sock > 0) {
|
||||
sock = c->setup.u.us.sock;
|
||||
qb_ipcc_us_sock_close(sock);
|
||||
c->setup.u.us.sock = -1;
|
||||
}
|
||||
if (c->request.type == QB_IPC_SOCKET) {
|
||||
sock = c->request.u.us.sock;
|
||||
}
|
||||
if (sock > 0) {
|
||||
(void)c->service->poll_fns.dispatch_del(sock);
|
||||
qb_ipcs_connection_unref(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qb_ipcs_us_disconnect(struct qb_ipcs_connection *c)
|
||||
{
|
||||
munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control));
|
||||
qb_enter();
|
||||
munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE);
|
||||
unlink(c->request.u.us.shared_file_name);
|
||||
|
||||
close(c->request.u.us.sock);
|
||||
close(c->event.u.us.sock);
|
||||
qb_ipcc_us_sock_close(c->request.u.us.sock);
|
||||
qb_ipcc_us_sock_close(c->event.u.us.sock);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
138
lib/ipcc.c
138
lib/ipcc.c
@ -20,9 +20,6 @@
|
||||
*/
|
||||
#include "os_base.h"
|
||||
|
||||
#ifdef HAVE_MQUEUE_H
|
||||
#include <mqueue.h>
|
||||
#endif /* HAVE_MQUEUE_H */
|
||||
#include "ipc_int.h"
|
||||
#include "util_int.h"
|
||||
#include <qb/qbdefs.h>
|
||||
@ -40,7 +37,8 @@ qb_ipcc_connect(const char *name, size_t max_msg_size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c->setup.max_msg_size = max_msg_size;
|
||||
c->setup.max_msg_size = QB_MAX(max_msg_size,
|
||||
sizeof(struct qb_ipc_connection_response));
|
||||
(void)strlcpy(c->name, name, NAME_MAX);
|
||||
res = qb_ipcc_us_setup_connect(c, &response);
|
||||
if (res < 0) {
|
||||
@ -54,7 +52,7 @@ qb_ipcc_connect(const char *name, size_t max_msg_size)
|
||||
c->response.max_msg_size = response.max_msg_size;
|
||||
c->request.max_msg_size = response.max_msg_size;
|
||||
c->event.max_msg_size = response.max_msg_size;
|
||||
c->receive_buf = malloc(response.max_msg_size);
|
||||
c->receive_buf = calloc(1, response.max_msg_size);
|
||||
c->fc_enable_max = 1;
|
||||
if (c->receive_buf == NULL) {
|
||||
res = -ENOMEM;
|
||||
@ -65,23 +63,13 @@ qb_ipcc_connect(const char *name, size_t max_msg_size)
|
||||
case QB_IPC_SHM:
|
||||
res = qb_ipcc_shm_connect(c, &response);
|
||||
break;
|
||||
case QB_IPC_POSIX_MQ:
|
||||
#ifdef HAVE_POSIX_MQ
|
||||
res = qb_ipcc_pmq_connect(c, &response);
|
||||
#else
|
||||
res = -ENOTSUP;
|
||||
#endif /* HAVE_POSIX_MQ */
|
||||
break;
|
||||
case QB_IPC_SYSV_MQ:
|
||||
#ifdef HAVE_SYSV_MQ
|
||||
res = qb_ipcc_smq_connect(c, &response);
|
||||
#else
|
||||
res = -ENOTSUP;
|
||||
#endif /* HAVE_SYSV_MQ */
|
||||
break;
|
||||
case QB_IPC_SOCKET:
|
||||
res = qb_ipcc_us_connect(c, &response);
|
||||
break;
|
||||
case QB_IPC_POSIX_MQ:
|
||||
case QB_IPC_SYSV_MQ:
|
||||
res = -ENOTSUP;
|
||||
break;
|
||||
default:
|
||||
res = -EINVAL;
|
||||
break;
|
||||
@ -100,6 +88,44 @@ disconnect_and_cleanup:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_check_connection_state(struct qb_ipcc_connection * c, int32_t res)
|
||||
{
|
||||
if (res >= 0) return;
|
||||
|
||||
if (qb_ipc_us_sock_error_is_disconnected(res)) {
|
||||
errno = -res;
|
||||
qb_util_perror(LOG_DEBUG,
|
||||
"interpreting result %d as a disconnect",
|
||||
res);
|
||||
c->is_connected = QB_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static struct qb_ipc_one_way *
|
||||
_event_sock_one_way_get(struct qb_ipcc_connection * c)
|
||||
{
|
||||
if (c->needs_sock_for_poll) {
|
||||
return &c->setup;
|
||||
}
|
||||
if (c->event.type == QB_IPC_SOCKET) {
|
||||
return &c->event;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct qb_ipc_one_way *
|
||||
_response_sock_one_way_get(struct qb_ipcc_connection * c)
|
||||
{
|
||||
if (c->needs_sock_for_poll) {
|
||||
return &c->setup;
|
||||
}
|
||||
if (c->response.type == QB_IPC_SOCKET) {
|
||||
return &c->response;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
qb_ipcc_send(struct qb_ipcc_connection * c, const void *msg_ptr, size_t msg_len)
|
||||
{
|
||||
@ -128,13 +154,13 @@ qb_ipcc_send(struct qb_ipcc_connection * c, const void *msg_ptr, size_t msg_len)
|
||||
res2 = qb_ipc_us_send(&c->setup, msg_ptr, 1);
|
||||
} while (res2 == -EAGAIN);
|
||||
if (res2 == -EPIPE) {
|
||||
c->is_connected = QB_FALSE;
|
||||
return -ENOTCONN;
|
||||
res2 = -ENOTCONN;
|
||||
}
|
||||
if (res2 != 1) {
|
||||
res = res2;
|
||||
}
|
||||
}
|
||||
_check_connection_state(c, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -183,13 +209,13 @@ qb_ipcc_sendv(struct qb_ipcc_connection * c, const struct iovec * iov,
|
||||
res2 = qb_ipc_us_send(&c->setup, &res, 1);
|
||||
} while (res2 == -EAGAIN);
|
||||
if (res2 == -EPIPE) {
|
||||
c->is_connected = QB_FALSE;
|
||||
return -ENOTCONN;
|
||||
res2 = -ENOTCONN;
|
||||
}
|
||||
if (res2 != 1) {
|
||||
res = res2;
|
||||
}
|
||||
}
|
||||
_check_connection_state(c, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -204,17 +230,17 @@ qb_ipcc_recv(struct qb_ipcc_connection * c, void *msg_ptr,
|
||||
}
|
||||
|
||||
res = c->funcs.recv(&c->response, msg_ptr, msg_len, ms_timeout);
|
||||
if ((res == -EAGAIN || res == -ETIMEDOUT) && c->needs_sock_for_poll) {
|
||||
res2 = qb_ipc_us_recv_ready(&c->setup, 0);
|
||||
if (res == -EAGAIN || res == -ETIMEDOUT) {
|
||||
struct qb_ipc_one_way *ow = _response_sock_one_way_get(c);
|
||||
|
||||
if (ow == NULL) return res;
|
||||
|
||||
res2 = qb_ipc_us_ready(ow, 0, POLLIN);
|
||||
if (res2 < 0) {
|
||||
if (res2 == -ENOTCONN) {
|
||||
c->is_connected = QB_FALSE;
|
||||
}
|
||||
return res2;
|
||||
} else {
|
||||
return res;
|
||||
res = res2;
|
||||
}
|
||||
}
|
||||
_check_connection_state(c, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -303,31 +329,23 @@ qb_ipcc_event_recv(struct qb_ipcc_connection * c, void *msg_pt,
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (c->needs_sock_for_poll) {
|
||||
ow = &c->setup;
|
||||
}
|
||||
if (c->event.type == QB_IPC_SOCKET) {
|
||||
ow = &c->event;
|
||||
}
|
||||
ow = _event_sock_one_way_get(c);
|
||||
if (ow) {
|
||||
res = qb_ipc_us_recv_ready(ow, ms_timeout);
|
||||
res = qb_ipc_us_ready(ow, ms_timeout, POLLIN);
|
||||
if (res < 0) {
|
||||
if (res == -ENOTCONN) {
|
||||
c->is_connected = QB_FALSE;
|
||||
}
|
||||
_check_connection_state(c, res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
size = c->funcs.recv(&c->event, msg_pt, msg_len, ms_timeout);
|
||||
if (size < 0) {
|
||||
_check_connection_state(c, size);
|
||||
return size;
|
||||
}
|
||||
if (c->needs_sock_for_poll) {
|
||||
res = qb_ipc_us_recv(&c->setup, &one_byte, 1, -1);
|
||||
if (res < 0) {
|
||||
if (res == -ENOTCONN) {
|
||||
c->is_connected = QB_FALSE;
|
||||
}
|
||||
_check_connection_state(c, res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -338,6 +356,7 @@ void
|
||||
qb_ipcc_disconnect(struct qb_ipcc_connection *c)
|
||||
{
|
||||
struct qb_ipc_one_way *ow = NULL;
|
||||
int32_t res = 0;
|
||||
|
||||
qb_util_log(LOG_DEBUG, "%s()", __func__);
|
||||
|
||||
@ -345,19 +364,13 @@ qb_ipcc_disconnect(struct qb_ipcc_connection *c)
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->needs_sock_for_poll) {
|
||||
ow = &c->setup;
|
||||
}
|
||||
if (c->event.type == QB_IPC_SOCKET) {
|
||||
ow = &c->event;
|
||||
}
|
||||
ow = _event_sock_one_way_get(c);
|
||||
if (ow) {
|
||||
if (qb_ipc_us_recv_ready(ow, 0) == -ENOTCONN) {
|
||||
c->is_connected = QB_FALSE;
|
||||
}
|
||||
res = qb_ipc_us_ready(ow, 0, POLLIN);
|
||||
_check_connection_state(c, res);
|
||||
qb_ipcc_us_sock_close(ow->u.us.sock);
|
||||
}
|
||||
|
||||
qb_ipcc_us_sock_close(c->setup.u.us.sock);
|
||||
if (c->funcs.disconnect) {
|
||||
c->funcs.disconnect(c);
|
||||
}
|
||||
@ -381,3 +394,20 @@ void *qb_ipcc_context_get(struct qb_ipcc_connection *c)
|
||||
}
|
||||
return c->context;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_ipcc_is_connected(qb_ipcc_connection_t *c)
|
||||
{
|
||||
struct qb_ipc_one_way *ow;
|
||||
|
||||
if (c == NULL) {
|
||||
return QB_FALSE;
|
||||
}
|
||||
|
||||
ow = _response_sock_one_way_get(c);
|
||||
if (ow) {
|
||||
_check_connection_state(c, qb_ipc_us_ready(ow, 0, POLLIN));
|
||||
}
|
||||
|
||||
return c->is_connected;
|
||||
}
|
||||
|
||||
231
lib/ipcs.c
231
lib/ipcs.c
@ -28,6 +28,8 @@
|
||||
|
||||
static void qb_ipcs_flowcontrol_set(struct qb_ipcs_connection *c,
|
||||
int32_t fc_enable);
|
||||
static int32_t
|
||||
new_event_notification(struct qb_ipcs_connection * c);
|
||||
|
||||
static QB_LIST_DECLARE(qb_ipc_services);
|
||||
|
||||
@ -42,9 +44,17 @@ qb_ipcs_create(const char *name,
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (type == QB_IPC_NATIVE) {
|
||||
#ifdef DISABLE_IPC_SHM
|
||||
s->type = QB_IPC_SOCKET;
|
||||
#else
|
||||
s->type = QB_IPC_SHM;
|
||||
#endif /* DISABLE_IPC_SHM */
|
||||
} else {
|
||||
s->type = type;
|
||||
}
|
||||
|
||||
s->pid = getpid();
|
||||
s->type = type;
|
||||
s->needs_sock_for_poll = QB_FALSE;
|
||||
s->poll_priority = QB_LOOP_MED;
|
||||
s->ref_count = 1;
|
||||
@ -91,21 +101,15 @@ qb_ipcs_run(struct qb_ipcs_service *s)
|
||||
qb_ipcs_us_init((struct qb_ipcs_service *)s);
|
||||
break;
|
||||
case QB_IPC_SHM:
|
||||
#ifdef DISABLE_IPC_SHM
|
||||
res = -ENOTSUP;
|
||||
#else
|
||||
qb_ipcs_shm_init((struct qb_ipcs_service *)s);
|
||||
#endif /* DISABLE_IPC_SHM */
|
||||
break;
|
||||
case QB_IPC_POSIX_MQ:
|
||||
#ifdef HAVE_POSIX_MQ
|
||||
qb_ipcs_pmq_init((struct qb_ipcs_service *)s);
|
||||
#else
|
||||
res = -ENOTSUP;
|
||||
#endif /* HAVE_POSIX_MQ */
|
||||
break;
|
||||
case QB_IPC_SYSV_MQ:
|
||||
#ifdef HAVE_SYSV_MQ
|
||||
qb_ipcs_smq_init((struct qb_ipcs_service *)s);
|
||||
#else
|
||||
res = -ENOTSUP;
|
||||
#endif /* HAVE_SYSV_MQ */
|
||||
break;
|
||||
default:
|
||||
res = -EINVAL;
|
||||
@ -130,15 +134,7 @@ _modify_dispatch_descriptor_(struct qb_ipcs_connection *c)
|
||||
{
|
||||
qb_ipcs_dispatch_mod_fn disp_mod = c->service->poll_fns.dispatch_mod;
|
||||
|
||||
if (c->service->type == QB_IPC_POSIX_MQ
|
||||
&& !c->service->needs_sock_for_poll) {
|
||||
#ifdef HAVE_MQUEUE_H
|
||||
return disp_mod(c->service->poll_priority,
|
||||
(int32_t) c->request.u.pmq.q,
|
||||
c->poll_events, c,
|
||||
qb_ipcs_dispatch_service_request);
|
||||
#endif /* HAVE_MQUEUE_H */
|
||||
} else if (c->service->type == QB_IPC_SOCKET) {
|
||||
if (c->service->type == QB_IPC_SOCKET) {
|
||||
return disp_mod(c->service->poll_priority,
|
||||
c->event.u.us.sock,
|
||||
c->poll_events, c,
|
||||
@ -236,6 +232,29 @@ qb_ipcs_destroy(struct qb_ipcs_service *s)
|
||||
/*
|
||||
* connection API
|
||||
*/
|
||||
static struct qb_ipc_one_way *
|
||||
_event_sock_one_way_get(struct qb_ipcs_connection * c)
|
||||
{
|
||||
if (c->service->needs_sock_for_poll) {
|
||||
return &c->setup;
|
||||
}
|
||||
if (c->event.type == QB_IPC_SOCKET) {
|
||||
return &c->event;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct qb_ipc_one_way *
|
||||
_response_sock_one_way_get(struct qb_ipcs_connection * c)
|
||||
{
|
||||
if (c->service->needs_sock_for_poll) {
|
||||
return &c->setup;
|
||||
}
|
||||
if (c->response.type == QB_IPC_SOCKET) {
|
||||
return &c->response;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
qb_ipcs_response_send(struct qb_ipcs_connection *c, const void *data,
|
||||
@ -251,6 +270,13 @@ qb_ipcs_response_send(struct qb_ipcs_connection *c, const void *data,
|
||||
if (res == size) {
|
||||
c->stats.responses++;
|
||||
} else if (res == -EAGAIN || res == -ETIMEDOUT) {
|
||||
struct qb_ipc_one_way *ow = _response_sock_one_way_get(c);
|
||||
if (ow) {
|
||||
ssize_t res2 = qb_ipc_us_ready(ow, 0, POLLOUT);
|
||||
if (res2 < 0) {
|
||||
res = res2;
|
||||
}
|
||||
}
|
||||
c->stats.send_retries++;
|
||||
}
|
||||
qb_ipcs_connection_unref(c);
|
||||
@ -272,6 +298,13 @@ qb_ipcs_response_sendv(struct qb_ipcs_connection * c, const struct iovec * iov,
|
||||
if (res > 0) {
|
||||
c->stats.responses++;
|
||||
} else if (res == -EAGAIN || res == -ETIMEDOUT) {
|
||||
struct qb_ipc_one_way *ow = _response_sock_one_way_get(c);
|
||||
if (ow) {
|
||||
ssize_t res2 = qb_ipc_us_ready(ow, 0, POLLOUT);
|
||||
if (res2 < 0) {
|
||||
res = res2;
|
||||
}
|
||||
}
|
||||
c->stats.send_retries++;
|
||||
}
|
||||
qb_ipcs_connection_unref(c);
|
||||
@ -285,7 +318,7 @@ resend_event_notifications(struct qb_ipcs_connection *c)
|
||||
ssize_t res = 0;
|
||||
|
||||
if (c->outstanding_notifiers > 0) {
|
||||
res = qb_ipc_us_send(&c->setup, &c->outstanding_notifiers,
|
||||
res = qb_ipc_us_send(&c->setup, c->receive_buf,
|
||||
c->outstanding_notifiers);
|
||||
}
|
||||
if (res > 0) {
|
||||
@ -313,15 +346,14 @@ new_event_notification(struct qb_ipcs_connection * c)
|
||||
c->outstanding_notifiers++;
|
||||
} else {
|
||||
res = qb_ipc_us_send(&c->setup, &c->outstanding_notifiers, 1);
|
||||
if (res == 1) {
|
||||
return res;
|
||||
if (res == -EAGAIN) {
|
||||
/*
|
||||
* notify the client later, when we can.
|
||||
*/
|
||||
c->outstanding_notifiers++;
|
||||
c->poll_events = POLLOUT | POLLIN | POLLPRI | POLLNVAL;
|
||||
(void)_modify_dispatch_descriptor_(c);
|
||||
}
|
||||
/*
|
||||
* notify the client later, when we can.
|
||||
*/
|
||||
c->outstanding_notifiers++;
|
||||
c->poll_events = POLLOUT | POLLIN | POLLPRI | POLLNVAL;
|
||||
(void)_modify_dispatch_descriptor_(c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -343,8 +375,20 @@ qb_ipcs_event_send(struct qb_ipcs_connection * c, const void *data, size_t size)
|
||||
resn = new_event_notification(c);
|
||||
if (resn < 0 && resn != -EAGAIN) {
|
||||
errno = -resn;
|
||||
qb_util_perror(LOG_WARNING, "new_event_notification");
|
||||
qb_util_perror(LOG_WARNING,
|
||||
"new_event_notification (%s)",
|
||||
c->description);
|
||||
res = resn;
|
||||
}
|
||||
} else if (res == -EAGAIN || res == -ETIMEDOUT) {
|
||||
struct qb_ipc_one_way *ow = _event_sock_one_way_get(c);
|
||||
if (ow) {
|
||||
resn = qb_ipc_us_ready(ow, 0, POLLOUT);
|
||||
if (resn < 0) {
|
||||
res = resn;
|
||||
}
|
||||
}
|
||||
c->stats.send_retries++;
|
||||
}
|
||||
|
||||
qb_ipcs_connection_unref(c);
|
||||
@ -369,8 +413,20 @@ qb_ipcs_event_sendv(struct qb_ipcs_connection * c,
|
||||
resn = new_event_notification(c);
|
||||
if (resn < 0 && resn != -EAGAIN) {
|
||||
errno = -resn;
|
||||
qb_util_perror(LOG_WARNING, "new_event_notification");
|
||||
qb_util_perror(LOG_WARNING,
|
||||
"new_event_notification (%s)",
|
||||
c->description);
|
||||
res = resn;
|
||||
}
|
||||
} else if (res == -EAGAIN || res == -ETIMEDOUT) {
|
||||
struct qb_ipc_one_way *ow = _event_sock_one_way_get(c);
|
||||
if (ow) {
|
||||
resn = qb_ipc_us_ready(ow, 0, POLLOUT);
|
||||
if (resn < 0) {
|
||||
res = resn;
|
||||
}
|
||||
}
|
||||
c->stats.send_retries++;
|
||||
}
|
||||
|
||||
qb_ipcs_connection_unref(c);
|
||||
@ -447,6 +503,7 @@ qb_ipcs_connection_alloc(struct qb_ipcs_service *s)
|
||||
c->request.type = s->type;
|
||||
c->response.type = s->type;
|
||||
c->event.type = s->type;
|
||||
(void)strlcpy(c->description, "not set yet", CONNECTION_DESCRIPTION);
|
||||
|
||||
return c;
|
||||
}
|
||||
@ -468,9 +525,9 @@ qb_ipcs_connection_unref(struct qb_ipcs_connection *c)
|
||||
return;
|
||||
}
|
||||
if (c->refcount < 1) {
|
||||
qb_util_log(LOG_ERR, "ref:%d state:%d fd:%d",
|
||||
qb_util_log(LOG_ERR, "ref:%d state:%d (%s)",
|
||||
c->refcount, c->state,
|
||||
c->setup.u.us.sock);
|
||||
c->description);
|
||||
assert(0);
|
||||
}
|
||||
free_it = qb_atomic_int_dec_and_test(&c->refcount);
|
||||
@ -494,17 +551,14 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c)
|
||||
if (c == NULL) {
|
||||
return;
|
||||
}
|
||||
qb_util_log(LOG_DEBUG, "%s() state:%d", __func__, c->state);
|
||||
qb_util_log(LOG_DEBUG, "%s(%s) state:%d",
|
||||
__func__, c->description, c->state);
|
||||
|
||||
if (c->state == QB_IPCS_CONNECTION_ACTIVE) {
|
||||
c->state = QB_IPCS_CONNECTION_INACTIVE;
|
||||
c->service->stats.closed_connections++;
|
||||
if (c->service->needs_sock_for_poll && c->setup.u.us.sock > 0) {
|
||||
(void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock);
|
||||
qb_ipcc_us_sock_close(c->setup.u.us.sock);
|
||||
c->setup.u.us.sock = -1;
|
||||
qb_ipcs_connection_unref(c);
|
||||
}
|
||||
|
||||
qb_ipcs_sockets_disconnect(c);
|
||||
/* return early as it's an incomplete connection.
|
||||
*/
|
||||
return;
|
||||
@ -514,12 +568,7 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c)
|
||||
c->service->stats.active_connections--;
|
||||
c->service->stats.closed_connections++;
|
||||
|
||||
if (c->service->needs_sock_for_poll && c->setup.u.us.sock > 0) {
|
||||
(void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock);
|
||||
qb_ipcc_us_sock_close(c->setup.u.us.sock);
|
||||
c->setup.u.us.sock = -1;
|
||||
qb_ipcs_connection_unref(c);
|
||||
}
|
||||
qb_ipcs_sockets_disconnect(c);
|
||||
}
|
||||
if (c->state == QB_IPCS_CONNECTION_SHUTTING_DOWN) {
|
||||
res = 0;
|
||||
@ -580,20 +629,21 @@ _process_request_(struct qb_ipcs_connection *c, int32_t ms_timeout)
|
||||
if (size < 0) {
|
||||
if (size != -EAGAIN && size != -ETIMEDOUT) {
|
||||
qb_util_perror(LOG_ERR,
|
||||
"recv from client connection failed");
|
||||
"recv from client connection failed (%s)",
|
||||
c->description);
|
||||
} else {
|
||||
c->stats.recv_retries++;
|
||||
}
|
||||
res = size;
|
||||
goto cleanup;
|
||||
}
|
||||
c->stats.requests++;
|
||||
|
||||
if (hdr->id == QB_IPC_MSG_DISCONNECT) {
|
||||
qb_util_log(LOG_DEBUG, "client requesting a disconnect");
|
||||
} else if (size == 0 || hdr->id == QB_IPC_MSG_DISCONNECT) {
|
||||
qb_util_log(LOG_DEBUG, "client requesting a disconnect (%s)",
|
||||
c->description);
|
||||
qb_ipcs_disconnect(c);
|
||||
c = NULL;
|
||||
res = -ESHUTDOWN;
|
||||
} else {
|
||||
c->stats.requests++;
|
||||
res = c->service->serv_fns.msg_process(c, hdr, hdr->size);
|
||||
/* 0 == good, negative == backoff */
|
||||
if (res < 0) {
|
||||
@ -603,7 +653,7 @@ _process_request_(struct qb_ipcs_connection *c, int32_t ms_timeout)
|
||||
}
|
||||
}
|
||||
|
||||
if (c->service->funcs.peek && c->service->funcs.reclaim) {
|
||||
if (c && c->service->funcs.peek && c->service->funcs.reclaim) {
|
||||
c->service->funcs.reclaim(&c->request);
|
||||
}
|
||||
|
||||
@ -658,8 +708,12 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data)
|
||||
int32_t recvd = 0;
|
||||
ssize_t avail;
|
||||
|
||||
if (revents & POLLNVAL) {
|
||||
qb_util_log(LOG_DEBUG, "NVAL conn (%s)", c->description);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (revents & POLLHUP) {
|
||||
qb_util_log(LOG_DEBUG, "HUP conn:%p fd:%d", c, fd);
|
||||
qb_util_log(LOG_DEBUG, "HUP conn (%s)", c->description);
|
||||
qb_ipcs_disconnect(c);
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
@ -668,7 +722,9 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data)
|
||||
res = resend_event_notifications(c);
|
||||
if (res < 0 && res != -EAGAIN) {
|
||||
errno = -res;
|
||||
qb_util_perror(LOG_WARNING, "resend_event_notifications");
|
||||
qb_util_perror(LOG_WARNING,
|
||||
"resend_event_notifications (%s)",
|
||||
c->description);
|
||||
}
|
||||
if ((revents & POLLIN) == 0) {
|
||||
return 0;
|
||||
@ -681,10 +737,18 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data)
|
||||
|
||||
if (c->service->needs_sock_for_poll && avail == 0) {
|
||||
res2 = qb_ipc_us_recv(&c->setup, bytes, 1, 0);
|
||||
qb_util_log(LOG_WARNING,
|
||||
"conn:%p Nothing in q but got POLLIN on fd:%d (res2:%d)",
|
||||
c, fd, res2);
|
||||
return 0;
|
||||
if (qb_ipc_us_sock_error_is_disconnected(res2)) {
|
||||
errno = -res2;
|
||||
qb_util_perror(LOG_WARNING, "conn (%s) disconnected",
|
||||
c->description);
|
||||
qb_ipcs_disconnect(c);
|
||||
return -ESHUTDOWN;
|
||||
} else {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"conn (%s) Nothing in q but got POLLIN on fd:%d (res2:%d)",
|
||||
c->description, fd, res2);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
@ -701,7 +765,9 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data)
|
||||
res2 = qb_ipc_us_recv(&c->setup, bytes, recvd, -1);
|
||||
if (res2 < 0) {
|
||||
errno = -res2;
|
||||
qb_util_perror(LOG_ERR, "error receiving from setup sock");
|
||||
qb_util_perror(LOG_ERR,
|
||||
"error receiving from setup sock (%s)",
|
||||
c->description);
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,7 +777,8 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data)
|
||||
}
|
||||
if (res != 0) {
|
||||
errno = -res;
|
||||
qb_util_perror(LOG_ERR, "request returned error");
|
||||
qb_util_perror(LOG_ERR, "request returned error (%s)",
|
||||
c->description);
|
||||
qb_ipcs_connection_unref(c);
|
||||
}
|
||||
|
||||
@ -746,12 +813,41 @@ qb_ipcs_connection_stats_get(qb_ipcs_connection_t * c,
|
||||
}
|
||||
memcpy(stats, &c->stats, sizeof(struct qb_ipcs_connection_stats));
|
||||
if (clear_after_read) {
|
||||
memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats));
|
||||
memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats_2));
|
||||
c->stats.client_pid = c->pid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct qb_ipcs_connection_stats_2*
|
||||
qb_ipcs_connection_stats_get_2(qb_ipcs_connection_t *c,
|
||||
int32_t clear_after_read)
|
||||
{
|
||||
struct qb_ipcs_connection_stats_2* stats;
|
||||
|
||||
if (c == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
stats = calloc(1, sizeof(struct qb_ipcs_connection_stats_2));
|
||||
if (stats == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(stats, &c->stats, sizeof(struct qb_ipcs_connection_stats_2));
|
||||
|
||||
if (c->service->funcs.q_len_get) {
|
||||
stats->event_q_length = c->service->funcs.q_len_get(&c->event);
|
||||
} else {
|
||||
stats->event_q_length = 0;
|
||||
}
|
||||
if (clear_after_read) {
|
||||
memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats_2));
|
||||
c->stats.client_pid = c->pid;
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_ipcs_stats_get(struct qb_ipcs_service * s,
|
||||
struct qb_ipcs_stats * stats, int32_t clear_after_read)
|
||||
@ -765,3 +861,14 @@ qb_ipcs_stats_get(struct qb_ipcs_service * s,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
qb_ipcs_connection_auth_set(qb_ipcs_connection_t *c, uid_t uid,
|
||||
gid_t gid, mode_t mode)
|
||||
{
|
||||
if (c) {
|
||||
c->auth.uid = uid;
|
||||
c->auth.gid = gid;
|
||||
c->auth.mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,5 +7,5 @@ Name: libqb
|
||||
Version: @PACKAGE_VERSION@
|
||||
Description: libqb
|
||||
Requires:
|
||||
Libs: -L${libdir} -lqb @LIB_RT@ -ldl
|
||||
Libs: -L${libdir} -lqb @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
|
||||
15
lib/log.c
15
lib/log.c
@ -225,7 +225,7 @@ qb_log_thread_log_write(struct qb_log_callsite *cs,
|
||||
if (t->state != QB_LOG_STATE_ENABLED) {
|
||||
continue;
|
||||
}
|
||||
if (t->threaded) {
|
||||
if (!t->threaded) {
|
||||
continue;
|
||||
}
|
||||
if (qb_bit_is_set(cs->targets, t->pos)) {
|
||||
@ -287,6 +287,11 @@ qb_log_callsite_get(const char *function,
|
||||
_custom_filter_fn(cs);
|
||||
}
|
||||
pthread_rwlock_unlock(&_listlock);
|
||||
} else if (cs->tags != tags) {
|
||||
cs->tags = tags;
|
||||
if (_custom_filter_fn) {
|
||||
_custom_filter_fn(cs);
|
||||
}
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
@ -730,6 +735,7 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
|
||||
for (i = 0; i < QB_LOG_TARGET_MAX; i++) {
|
||||
conf[i].pos = i;
|
||||
conf[i].debug = QB_FALSE;
|
||||
conf[i].file_sync = QB_FALSE;
|
||||
conf[i].state = QB_LOG_STATE_UNUSED;
|
||||
(void)strlcpy(conf[i].name, name, PATH_MAX);
|
||||
conf[i].facility = facility;
|
||||
@ -894,7 +900,9 @@ qb_log_custom_close(int32_t t)
|
||||
target = qb_log_target_get(t);
|
||||
|
||||
if (target->close) {
|
||||
in_logger = QB_TRUE;
|
||||
target->close(t);
|
||||
in_logger = QB_FALSE;
|
||||
}
|
||||
qb_log_target_free(target);
|
||||
}
|
||||
@ -965,6 +973,9 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
|
||||
need_reload = QB_TRUE;
|
||||
}
|
||||
break;
|
||||
case QB_LOG_CONF_FILE_SYNC:
|
||||
conf[t].file_sync = arg;
|
||||
break;
|
||||
case QB_LOG_CONF_PRIORITY_BUMP:
|
||||
conf[t].priority_bump = arg;
|
||||
break;
|
||||
@ -987,7 +998,9 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
|
||||
rc = -EINVAL;
|
||||
}
|
||||
if (rc == 0 && need_reload && conf[t].reload) {
|
||||
in_logger = QB_TRUE;
|
||||
conf[t].reload(t);
|
||||
in_logger = QB_FALSE;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -38,6 +38,8 @@ _blackbox_reload(int32_t target)
|
||||
}
|
||||
|
||||
/* <u32> file lineno
|
||||
* <u32> tags
|
||||
* <u8> priority
|
||||
* <u32> function name length
|
||||
* <string> function name
|
||||
* <u32> buffer length
|
||||
@ -49,8 +51,10 @@ _blackbox_vlogger(int32_t target,
|
||||
{
|
||||
size_t max_size;
|
||||
size_t actual_size;
|
||||
size_t fn_size;
|
||||
uint32_t fn_size;
|
||||
char *chunk;
|
||||
char *msg_len_pt;
|
||||
uint32_t msg_len;
|
||||
struct qb_log_target *t = qb_log_target_get(target);
|
||||
|
||||
if (t->instance == NULL) {
|
||||
@ -59,7 +63,7 @@ _blackbox_vlogger(int32_t target,
|
||||
|
||||
fn_size = strlen(cs->function) + 1;
|
||||
|
||||
actual_size = 2 * sizeof(uint32_t) + fn_size + sizeof(time_t);
|
||||
actual_size = 4 * sizeof(uint32_t) + sizeof(uint8_t) + fn_size + sizeof(time_t);
|
||||
max_size = actual_size + QB_LOG_MAX_LEN;
|
||||
|
||||
chunk = qb_rb_chunk_alloc(t->instance, max_size);
|
||||
@ -68,6 +72,14 @@ _blackbox_vlogger(int32_t target,
|
||||
memcpy(chunk, &cs->lineno, sizeof(uint32_t));
|
||||
chunk += sizeof(uint32_t);
|
||||
|
||||
/* tags */
|
||||
memcpy(chunk, &cs->tags, sizeof(uint32_t));
|
||||
chunk += sizeof(uint32_t);
|
||||
|
||||
/* log level/priority */
|
||||
memcpy(chunk, &cs->priority, sizeof(uint8_t));
|
||||
chunk += sizeof(uint8_t);
|
||||
|
||||
/* function name */
|
||||
memcpy(chunk, &fn_size, sizeof(uint32_t));
|
||||
chunk += sizeof(uint32_t);
|
||||
@ -78,8 +90,26 @@ _blackbox_vlogger(int32_t target,
|
||||
memcpy(chunk, ×tamp, sizeof(time_t));
|
||||
chunk += sizeof(time_t);
|
||||
|
||||
/* log message length */
|
||||
msg_len_pt = chunk;
|
||||
chunk += sizeof(uint32_t);
|
||||
|
||||
/* log message */
|
||||
actual_size += qb_vsprintf_serialize(chunk, cs->format, ap);
|
||||
msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN, cs->format, ap);
|
||||
if(msg_len >= QB_LOG_MAX_LEN) {
|
||||
chunk = msg_len_pt + sizeof(uint32_t); /* Reset */
|
||||
|
||||
msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN,
|
||||
"Log message too long to be stored in the blackbox. "\
|
||||
"Maximum is QB_LOG_MAX_LEN" , ap);
|
||||
actual_size += msg_len;
|
||||
}
|
||||
|
||||
actual_size += msg_len;
|
||||
|
||||
/* now that we know the length, write it
|
||||
*/
|
||||
memcpy(msg_len_pt, &msg_len, sizeof(uint32_t));
|
||||
|
||||
(void)qb_rb_chunk_commit(t->instance, actual_size);
|
||||
}
|
||||
@ -142,7 +172,8 @@ qb_log_blackbox_print_from_file(const char *bb_filename)
|
||||
{
|
||||
qb_ringbuffer_t *instance;
|
||||
ssize_t bytes_read;
|
||||
char chunk[512];
|
||||
int max_size = 2 * QB_LOG_MAX_LEN;
|
||||
char *chunk;
|
||||
int fd;
|
||||
char time_buf[64];
|
||||
|
||||
@ -156,17 +187,21 @@ qb_log_blackbox_print_from_file(const char *bb_filename)
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
chunk = malloc(max_size);
|
||||
|
||||
do {
|
||||
char *ptr;
|
||||
uint32_t lineno;
|
||||
uint32_t tags;
|
||||
uint8_t priority;
|
||||
uint32_t fn_size;
|
||||
char *function;
|
||||
uint32_t len;
|
||||
time_t timestamp;
|
||||
uint32_t msg_len;
|
||||
char message[QB_LOG_MAX_LEN];
|
||||
|
||||
bytes_read = qb_rb_chunk_read(instance, chunk, 512, 0);
|
||||
bytes_read = qb_rb_chunk_read(instance, chunk, max_size, 0);
|
||||
ptr = chunk;
|
||||
if (bytes_read > 0) {
|
||||
struct tm *tm;
|
||||
@ -174,6 +209,14 @@ qb_log_blackbox_print_from_file(const char *bb_filename)
|
||||
memcpy(&lineno, ptr, sizeof(uint32_t));
|
||||
ptr += sizeof(uint32_t);
|
||||
|
||||
/* tags */
|
||||
memcpy(&tags, ptr, sizeof(uint32_t));
|
||||
ptr += sizeof(uint32_t);
|
||||
|
||||
/* priority */
|
||||
memcpy(&priority, ptr, sizeof(uint8_t));
|
||||
ptr += sizeof(uint8_t);
|
||||
|
||||
/* function size & name */
|
||||
memcpy(&fn_size, ptr, sizeof(uint32_t));
|
||||
ptr += sizeof(uint32_t);
|
||||
@ -182,7 +225,7 @@ qb_log_blackbox_print_from_file(const char *bb_filename)
|
||||
ptr += fn_size;
|
||||
|
||||
/* timestamp size & content */
|
||||
memcpy(×tamp, ptr, sizeof(uint32_t));
|
||||
memcpy(×tamp, ptr, sizeof(time_t));
|
||||
ptr += sizeof(time_t);
|
||||
tm = localtime(×tamp);
|
||||
if (tm) {
|
||||
@ -193,6 +236,10 @@ qb_log_blackbox_print_from_file(const char *bb_filename)
|
||||
snprintf(time_buf, sizeof(time_buf), "%ld",
|
||||
(long int)timestamp);
|
||||
}
|
||||
/* message length */
|
||||
memcpy(&msg_len, ptr, sizeof(uint32_t));
|
||||
ptr += sizeof(uint32_t);
|
||||
|
||||
/* message content */
|
||||
len = qb_vsnprintf_deserialize(message, QB_LOG_MAX_LEN, ptr);
|
||||
len--;
|
||||
@ -200,8 +247,12 @@ qb_log_blackbox_print_from_file(const char *bb_filename)
|
||||
message[len] = '\0';
|
||||
len--;
|
||||
}
|
||||
printf("%s %s():%d %s\n",
|
||||
time_buf, function, lineno, message);
|
||||
message[msg_len] = '\0';
|
||||
printf("%-7s %s %s(%u):%u: %s\n",
|
||||
qb_log_priority2str(priority),
|
||||
time_buf, function, lineno, tags, message);
|
||||
}
|
||||
} while (bytes_read > 0);
|
||||
qb_rb_close(instance);
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ qb_log_dcs_get(int32_t * newly_created,
|
||||
int32_t rc;
|
||||
struct qb_log_callsite *cs = NULL;
|
||||
struct callsite_list *csl_head;
|
||||
struct callsite_list *csl_last;
|
||||
struct callsite_list *csl_last = NULL;
|
||||
struct callsite_list *csl;
|
||||
const char *safe_filename = filename;
|
||||
const char *safe_function = function;
|
||||
@ -196,6 +196,27 @@ qb_log_dcs_init(void)
|
||||
void
|
||||
qb_log_dcs_fini(void)
|
||||
{
|
||||
struct callsite_list *csl_head;
|
||||
struct callsite_list *csl_next;
|
||||
struct callsite_list *csl;
|
||||
int32_t i;
|
||||
int32_t rc;
|
||||
int32_t cnt = qb_array_num_bins_get(lookup_arr);
|
||||
cnt *= qb_array_elems_per_bin_get(lookup_arr);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
rc = qb_array_index(lookup_arr, i, (void **)&csl_head);
|
||||
if (rc != 0 || csl_head->next == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (csl = csl_head->next; csl; csl = csl_next) {
|
||||
csl_next = csl->next;
|
||||
free(csl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qb_array_free(lookup_arr);
|
||||
qb_array_free(callsite_arr);
|
||||
(void)qb_thread_lock_destroy(arr_next_lock);
|
||||
|
||||
@ -26,6 +26,7 @@ _file_logger(int32_t t,
|
||||
struct qb_log_callsite *cs, time_t timestamp, const char *msg)
|
||||
{
|
||||
char output_buffer[QB_LOG_MAX_LEN];
|
||||
struct qb_log_target *target = qb_log_target_get(t);
|
||||
FILE *f = qb_log_target_user_data_get(t);
|
||||
|
||||
if (f == NULL) {
|
||||
@ -36,7 +37,11 @@ _file_logger(int32_t t,
|
||||
qb_log_target_format(t, cs, timestamp, msg, output_buffer);
|
||||
|
||||
fprintf(f, "%s\n", output_buffer);
|
||||
|
||||
fflush(f);
|
||||
if (target->file_sync) {
|
||||
fsync(fileno(f));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
101
lib/log_format.c
101
lib/log_format.c
@ -51,10 +51,14 @@ static struct syslog_names prioritynames[] = {
|
||||
|
||||
struct syslog_names facilitynames[] = {
|
||||
{"auth", LOG_AUTH},
|
||||
#if defined(LOG_AUTHPRIV)
|
||||
{"authpriv", LOG_AUTHPRIV},
|
||||
#endif
|
||||
{"cron", LOG_CRON},
|
||||
{"daemon", LOG_DAEMON},
|
||||
#if defined(LOG_FTP)
|
||||
{"ftp", LOG_FTP},
|
||||
#endif
|
||||
{"kern", LOG_KERN},
|
||||
{"lpr", LOG_LPR},
|
||||
{"mail", LOG_MAIL},
|
||||
@ -110,6 +114,15 @@ qb_log_facility2str(int32_t fnum)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
qb_log_priority2str(uint8_t priority)
|
||||
{
|
||||
if (priority > LOG_TRACE) {
|
||||
return prioritynames[LOG_TRACE].c_name;
|
||||
}
|
||||
return prioritynames[priority].c_name;
|
||||
}
|
||||
|
||||
void
|
||||
qb_log_tags_stringify_fn_set(qb_log_tags_stringify_fn fn)
|
||||
{
|
||||
@ -366,16 +379,16 @@ qb_log_target_format(int32_t target,
|
||||
}
|
||||
|
||||
size_t
|
||||
qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap)
|
||||
qb_vsnprintf_serialize(char *serialize, size_t max_len,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
char *format;
|
||||
char *p;
|
||||
uint32_t location = 0;
|
||||
int type_long = 0;
|
||||
int type_longlong = 0;
|
||||
|
||||
p = stpcpy(serialize, fmt);
|
||||
location = p - serialize + 1;
|
||||
int sformat_length = 0;
|
||||
int sformat_precision = 0;
|
||||
uint32_t location = strlcpy(serialize, fmt, max_len) + 1;
|
||||
|
||||
format = (char *)fmt;
|
||||
for (;;) {
|
||||
@ -394,7 +407,12 @@ reprocess:
|
||||
case '+': /* a sign should be used, ignore */
|
||||
case '\'': /* group in thousands, ignore */
|
||||
case 'I': /* glibc-ism locale alternative, ignore */
|
||||
format++;
|
||||
goto reprocess;
|
||||
case '.': /* precision, ignore */
|
||||
format++;
|
||||
sformat_precision = 1;
|
||||
goto reprocess;
|
||||
case '0': /* field width, ignore */
|
||||
case '1': /* field width, ignore */
|
||||
case '2': /* field width, ignore */
|
||||
@ -405,11 +423,17 @@ reprocess:
|
||||
case '7': /* field width, ignore */
|
||||
case '8': /* field width, ignore */
|
||||
case '9': /* field width, ignore */
|
||||
if(sformat_precision) {
|
||||
sformat_length *= 10;
|
||||
sformat_length += (format[0] - '0');
|
||||
}
|
||||
format++;
|
||||
goto reprocess;
|
||||
|
||||
case '*': /* variable field width, save */ {
|
||||
int arg_int = va_arg(ap, int);
|
||||
if (location + sizeof (int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
memcpy(&serialize[location], &arg_int, sizeof (int));
|
||||
location += sizeof(int);
|
||||
format++;
|
||||
@ -433,6 +457,9 @@ reprocess:
|
||||
if (type_long) {
|
||||
long int arg_int;
|
||||
|
||||
if (location + sizeof (long int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, long int);
|
||||
memcpy(&serialize[location], &arg_int,
|
||||
sizeof(long int));
|
||||
@ -442,6 +469,9 @@ reprocess:
|
||||
} else if (type_longlong) {
|
||||
long long int arg_int;
|
||||
|
||||
if (location + sizeof (long long int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, long long int);
|
||||
memcpy(&serialize[location], &arg_int,
|
||||
sizeof(long long int));
|
||||
@ -451,6 +481,9 @@ reprocess:
|
||||
} else {
|
||||
int arg_int;
|
||||
|
||||
if (location + sizeof (int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, int);
|
||||
memcpy(&serialize[location], &arg_int,
|
||||
sizeof(int));
|
||||
@ -469,6 +502,9 @@ reprocess:
|
||||
{
|
||||
double arg_double;
|
||||
|
||||
if (location + sizeof (double) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_double = va_arg(ap, double);
|
||||
memcpy (&serialize[location], &arg_double, sizeof (double));
|
||||
location += sizeof(double);
|
||||
@ -480,6 +516,9 @@ reprocess:
|
||||
int arg_int;
|
||||
unsigned char arg_char;
|
||||
|
||||
if (location + sizeof (unsigned int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, unsigned int);
|
||||
arg_char = (unsigned char)arg_int;
|
||||
memcpy (&serialize[location], &arg_char, sizeof (unsigned char));
|
||||
@ -490,20 +529,42 @@ reprocess:
|
||||
{
|
||||
char *arg_string;
|
||||
arg_string = va_arg(ap, char *);
|
||||
p = stpcpy(&serialize[location], arg_string);
|
||||
location += p - &serialize[location] + 1;
|
||||
if (arg_string == NULL) {
|
||||
location += strlcpy(&serialize[location],
|
||||
"(null)",
|
||||
QB_MIN(strlen("(null)") + 1,
|
||||
max_len - location));
|
||||
} else if (sformat_length) {
|
||||
location += strlcpy(&serialize[location],
|
||||
arg_string,
|
||||
QB_MIN(sformat_length + 1,
|
||||
(max_len - location)));
|
||||
} else {
|
||||
location += strlcpy(&serialize[location],
|
||||
arg_string,
|
||||
QB_MIN(strlen(arg_string) + 1,
|
||||
max_len - location));
|
||||
}
|
||||
location++;
|
||||
break;
|
||||
}
|
||||
case 'p':
|
||||
{
|
||||
void *arg_pointer;
|
||||
arg_pointer = va_arg(ap, void *);
|
||||
memcpy (&serialize[location], &arg_pointer, sizeof (void *));
|
||||
location += sizeof (arg_pointer);
|
||||
ptrdiff_t arg_pointer = va_arg(ap, ptrdiff_t);
|
||||
if (location + sizeof (ptrdiff_t) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
memcpy(&serialize[location], &arg_pointer, sizeof(ptrdiff_t));
|
||||
location += sizeof(ptrdiff_t);
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
if (location + 1 > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
serialize[location++] = '%';
|
||||
sformat_length = 0;
|
||||
sformat_precision = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
@ -527,19 +588,18 @@ qb_vsnprintf_deserialize(char *string, size_t str_len, const char *buf)
|
||||
int type_longlong = 0;
|
||||
int len;
|
||||
|
||||
string[0] = '\0';
|
||||
format = (char *)buf;
|
||||
for (;;) {
|
||||
type_long = 0;
|
||||
type_longlong = 0;
|
||||
p = strchrnul((const char *)format, '%');
|
||||
if (*p == '\0') {
|
||||
p = stpcpy(&string[location], format);
|
||||
location += p - &string[location] + 1;
|
||||
break;
|
||||
return strlcat(string, format, str_len) + 1;
|
||||
}
|
||||
/* copy from current to the next % */
|
||||
len = p - format;
|
||||
strncpy(&string[location], format, len);
|
||||
memcpy(&string[location], format, len);
|
||||
location += len;
|
||||
format = p;
|
||||
|
||||
@ -681,11 +741,14 @@ reprocess:
|
||||
}
|
||||
case 'p':
|
||||
{
|
||||
ptrdiff_t pt;
|
||||
memcpy(&pt, &buf[data_pos],
|
||||
sizeof(ptrdiff_t));
|
||||
fmt[fmt_pos++] = *format;
|
||||
fmt[fmt_pos++] = '\0';
|
||||
location = snprintf(&string[location],
|
||||
str_len - location,
|
||||
fmt, &buf[data_pos]);
|
||||
location += snprintf(&string[location],
|
||||
str_len - location,
|
||||
fmt, pt);
|
||||
data_pos += sizeof(void*);
|
||||
format++;
|
||||
break;
|
||||
|
||||
@ -35,6 +35,7 @@ struct qb_log_target {
|
||||
struct qb_list_head filter_head;
|
||||
int32_t facility;
|
||||
int32_t priority_bump;
|
||||
int32_t file_sync;
|
||||
int32_t debug;
|
||||
size_t size;
|
||||
char *format;
|
||||
@ -93,7 +94,8 @@ struct qb_log_callsite *qb_log_dcs_get(int32_t *newly_created,
|
||||
uint32_t lineno,
|
||||
uint32_t tags);
|
||||
|
||||
size_t qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap);
|
||||
const char * qb_log_priority2str(uint8_t priority);
|
||||
size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap);
|
||||
size_t qb_vsnprintf_deserialize(char *string, size_t str_len, const char *buf);
|
||||
|
||||
void qb_log_target_format_static(int32_t target, const char * format, char *output_buffer);
|
||||
|
||||
@ -121,7 +121,7 @@ qb_log_thread_priority_set(int32_t policy, int32_t priority)
|
||||
#ifdef SCHED_IDLE
|
||||
|| policy == SCHED_IDLE
|
||||
#endif
|
||||
#ifndef QB_DARWIN
|
||||
#if defined(SCHED_BATCH) && !defined(QB_DARWIN)
|
||||
|| policy == SCHED_BATCH
|
||||
#endif
|
||||
) {
|
||||
@ -152,6 +152,8 @@ qb_log_thread_start(void)
|
||||
}
|
||||
|
||||
wthread_active = 1;
|
||||
sem_init(&logt_thread_start, 0, 0);
|
||||
sem_init(&logt_print_finished, 0, 0);
|
||||
res = pthread_create(&logt_thread_id, NULL,
|
||||
qb_logt_worker_thread, NULL);
|
||||
if (res != 0) {
|
||||
@ -179,6 +181,8 @@ cleanup_pthread:
|
||||
wthread_should_exit = 1;
|
||||
sem_post(&logt_print_finished);
|
||||
pthread_join(logt_thread_id, NULL);
|
||||
sem_destroy(&logt_print_finished);
|
||||
sem_destroy(&logt_thread_start);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -270,4 +274,6 @@ qb_log_thread_stop(void)
|
||||
pthread_join(logt_thread_id, NULL);
|
||||
}
|
||||
(void)qb_thread_lock_destroy(logt_wthread_lock);
|
||||
sem_destroy(&logt_print_finished);
|
||||
sem_destroy(&logt_thread_start);
|
||||
}
|
||||
|
||||
309
lib/loop_poll.c
309
lib/loop_poll.c
@ -23,27 +23,10 @@
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_EPOLL_H
|
||||
#include <sys/epoll.h>
|
||||
#ifndef epoll_create1
|
||||
int epoll_create1(int flags);
|
||||
#endif /* workaround a set of sparc and alpha broken headers */
|
||||
#endif /* HAVE_SYS_EPOLL_H */
|
||||
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif /* HAVE_SYS_POLL_H */
|
||||
#ifndef S_SPLINT_S
|
||||
#endif /* S_SPLINT_S */
|
||||
#include <signal.h>
|
||||
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qblist.h>
|
||||
#include <qb/qbarray.h>
|
||||
#include <qb/qbloop.h>
|
||||
#include <qb/qbutil.h>
|
||||
#include "loop_int.h"
|
||||
#include "util_int.h"
|
||||
#include "loop_poll_int.h"
|
||||
|
||||
/*
|
||||
* Define this to log slow (>10ms) jobs.
|
||||
@ -53,77 +36,19 @@ int epoll_create1(int flags);
|
||||
/* logs, std(in|out|err), pipe */
|
||||
#define POLL_FDS_USED_MISC 50
|
||||
|
||||
struct qb_poll_entry;
|
||||
|
||||
typedef int32_t(*qb_poll_add_to_jobs_fn) (struct qb_loop * l,
|
||||
struct qb_poll_entry * pe);
|
||||
|
||||
struct qb_poll_entry {
|
||||
struct qb_loop_item item;
|
||||
qb_loop_poll_dispatch_fn poll_dispatch_fn;
|
||||
enum qb_loop_priority p;
|
||||
uint32_t install_pos;
|
||||
struct pollfd ufd;
|
||||
qb_poll_add_to_jobs_fn add_to_jobs;
|
||||
uint32_t runs;
|
||||
enum qb_poll_entry_state state;
|
||||
uint32_t check;
|
||||
};
|
||||
|
||||
struct qb_poll_source {
|
||||
struct qb_loop_source s;
|
||||
#ifdef HAVE_EPOLL
|
||||
int32_t epollfd;
|
||||
#define USE_EPOLL 1
|
||||
#else
|
||||
struct pollfd *ufds;
|
||||
#ifdef HAVE_KQUEUE
|
||||
#define USE_KQUEUE 1
|
||||
#else
|
||||
#define USE_POLL 1
|
||||
#endif /* HAVE_KQUEUE */
|
||||
#endif /* HAVE_EPOLL */
|
||||
int32_t poll_entry_count;
|
||||
qb_array_t *poll_entries;
|
||||
qb_loop_poll_low_fds_event_fn low_fds_event_fn;
|
||||
int32_t not_enough_fds;
|
||||
};
|
||||
|
||||
static int32_t _qb_signal_add_to_jobs_(struct qb_loop *l,
|
||||
struct qb_poll_entry *pe);
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
static int32_t
|
||||
_poll_to_epoll_event_(int32_t event)
|
||||
{
|
||||
int32_t out = 0;
|
||||
if (event & POLLIN)
|
||||
out |= EPOLLIN;
|
||||
if (event & POLLOUT)
|
||||
out |= EPOLLOUT;
|
||||
if (event & POLLPRI)
|
||||
out |= EPOLLPRI;
|
||||
if (event & POLLERR)
|
||||
out |= EPOLLERR;
|
||||
if (event & POLLHUP)
|
||||
out |= EPOLLHUP;
|
||||
if (event & POLLNVAL)
|
||||
out |= EPOLLERR;
|
||||
return out;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_epoll_to_poll_event_(int32_t event)
|
||||
{
|
||||
int32_t out = 0;
|
||||
if (event & EPOLLIN)
|
||||
out |= POLLIN;
|
||||
if (event & EPOLLOUT)
|
||||
out |= POLLOUT;
|
||||
if (event & EPOLLPRI)
|
||||
out |= POLLPRI;
|
||||
if (event & EPOLLERR)
|
||||
out |= POLLERR;
|
||||
if (event & EPOLLHUP)
|
||||
out |= POLLHUP;
|
||||
return out;
|
||||
}
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
static void
|
||||
_poll_entry_check_generate_(struct qb_poll_entry *pe)
|
||||
{
|
||||
@ -138,28 +63,6 @@ _poll_entry_check_generate_(struct qb_poll_entry *pe)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_EPOLL)
|
||||
static int32_t
|
||||
_poll_entry_from_handle_(struct qb_poll_source *s,
|
||||
uint64_t handle_in, struct qb_poll_entry **pe_pt)
|
||||
{
|
||||
int32_t res = 0;
|
||||
uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32));
|
||||
uint32_t handle = handle_in & 0xffffffff;
|
||||
struct qb_poll_entry *pe;
|
||||
|
||||
res = qb_array_index(s->poll_entries, handle, (void **)&pe);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
if (pe->check != check) {
|
||||
return -EINVAL;
|
||||
}
|
||||
*pe_pt = pe;
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
static void
|
||||
_poll_entry_mark_deleted_(struct qb_poll_entry *pe)
|
||||
{
|
||||
@ -224,8 +127,8 @@ _poll_dispatch_and_take_back_(struct qb_loop_item *item,
|
||||
#endif /* DEBUG_DISPATCH_TIME */
|
||||
}
|
||||
|
||||
static void
|
||||
_poll_fds_usage_check_(struct qb_poll_source *s)
|
||||
void
|
||||
qb_poll_fds_usage_check_(struct qb_poll_source *s)
|
||||
{
|
||||
struct rlimit lim;
|
||||
static int32_t socks_limit = 0;
|
||||
@ -279,107 +182,6 @@ _poll_fds_usage_check_(struct qb_poll_source *s)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
#define MAX_EVENTS 12
|
||||
static int32_t
|
||||
_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t res;
|
||||
int32_t event_count;
|
||||
int32_t new_jobs = 0;
|
||||
struct qb_poll_entry *pe = NULL;
|
||||
struct qb_poll_source *s = (struct qb_poll_source *)src;
|
||||
struct epoll_event events[MAX_EVENTS];
|
||||
|
||||
_poll_fds_usage_check_(s);
|
||||
|
||||
retry_poll:
|
||||
|
||||
event_count = epoll_wait(s->epollfd, events, MAX_EVENTS, ms_timeout);
|
||||
|
||||
if (errno == EINTR && event_count == -1) {
|
||||
goto retry_poll;
|
||||
} else if (event_count == -1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
for (i = 0; i < event_count; i++) {
|
||||
res = _poll_entry_from_handle_(s, events[i].data.u64, &pe);
|
||||
if (res != 0) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"can't find poll entry for new event.");
|
||||
continue;
|
||||
}
|
||||
if (pe->ufd.fd == -1 || pe->state == QB_POLL_ENTRY_DELETED) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"can't post new event to a deleted entry.");
|
||||
/*
|
||||
* empty/deleted
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (events[i].events == pe->ufd.revents ||
|
||||
pe->state == QB_POLL_ENTRY_JOBLIST) {
|
||||
/*
|
||||
* entry already in the job queue.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
pe->ufd.revents = _epoll_to_poll_event_(events[i].events);
|
||||
|
||||
new_jobs += pe->add_to_jobs(src->l, pe);
|
||||
}
|
||||
|
||||
return new_jobs;
|
||||
}
|
||||
#else
|
||||
static int32_t
|
||||
_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t res;
|
||||
int32_t new_jobs = 0;
|
||||
struct qb_poll_entry *pe;
|
||||
struct qb_poll_source *s = (struct qb_poll_source *)src;
|
||||
|
||||
_poll_fds_usage_check_(s);
|
||||
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0);
|
||||
memcpy(&s->ufds[i], &pe->ufd, sizeof(struct pollfd));
|
||||
}
|
||||
|
||||
retry_poll:
|
||||
res = poll(s->ufds, s->poll_entry_count, ms_timeout);
|
||||
if (errno == EINTR && res == -1) {
|
||||
goto retry_poll;
|
||||
} else if (res == -1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
if (s->ufds[i].fd == -1 || s->ufds[i].revents == 0) {
|
||||
/*
|
||||
* empty entry
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0);
|
||||
if (pe->state != QB_POLL_ENTRY_ACTIVE ||
|
||||
s->ufds[i].revents == pe->ufd.revents) {
|
||||
/*
|
||||
* Wrong state to accept an event.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
pe->ufd.revents = s->ufds[i].revents;
|
||||
new_jobs += pe->add_to_jobs(src->l, pe);
|
||||
}
|
||||
|
||||
return new_jobs;
|
||||
}
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
struct qb_loop_source *
|
||||
qb_loop_poll_create(struct qb_loop *l)
|
||||
@ -390,18 +192,21 @@ qb_loop_poll_create(struct qb_loop *l)
|
||||
}
|
||||
s->s.l = l;
|
||||
s->s.dispatch_and_take_back = _poll_dispatch_and_take_back_;
|
||||
s->s.poll = _poll_and_add_to_jobs_;
|
||||
|
||||
s->poll_entries = qb_array_create_2(16, sizeof(struct qb_poll_entry), 16);
|
||||
s->poll_entry_count = 0;
|
||||
s->low_fds_event_fn = NULL;
|
||||
s->not_enough_fds = 0;
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
s->epollfd = epoll_create1(EPOLL_CLOEXEC);
|
||||
#else
|
||||
s->ufds = 0;
|
||||
#endif /* HAVE_EPOLL */
|
||||
#ifdef USE_EPOLL
|
||||
(void)qb_epoll_init(s);
|
||||
#endif
|
||||
#ifdef USE_KQUEUE
|
||||
(void)qb_kqueue_init(s);
|
||||
#endif
|
||||
#ifdef USE_POLL
|
||||
(void)qb_poll_init(s);
|
||||
#endif /* USE_POLL */
|
||||
|
||||
return (struct qb_loop_source *)s;
|
||||
}
|
||||
@ -411,12 +216,9 @@ qb_loop_poll_destroy(struct qb_loop *l)
|
||||
{
|
||||
struct qb_poll_source *s = (struct qb_poll_source *)l->fd_source;
|
||||
qb_array_free(s->poll_entries);
|
||||
#ifdef HAVE_EPOLL
|
||||
if (s->epollfd != -1) {
|
||||
close(s->epollfd);
|
||||
s->epollfd = -1;
|
||||
}
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
s->driver.fini(s);
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
@ -437,10 +239,6 @@ _get_empty_array_position_(struct qb_poll_source *s)
|
||||
uint32_t install_pos;
|
||||
int32_t res = 0;
|
||||
struct qb_poll_entry *pe;
|
||||
#ifndef HAVE_EPOLL
|
||||
struct pollfd *ufds;
|
||||
int32_t new_size = 0;
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
for (found = 0, install_pos = 0;
|
||||
install_pos < s->poll_entry_count; install_pos++) {
|
||||
@ -453,6 +251,15 @@ _get_empty_array_position_(struct qb_poll_source *s)
|
||||
}
|
||||
|
||||
if (found == 0) {
|
||||
#ifdef USE_POLL
|
||||
struct pollfd *ufds;
|
||||
int32_t new_size = (s->poll_entry_count + 1) * sizeof(struct pollfd);
|
||||
ufds = realloc(s->ufds, new_size);
|
||||
if (ufds == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
s->ufds = ufds;
|
||||
#endif /* USE_POLL */
|
||||
/*
|
||||
* Grow pollfd list
|
||||
*/
|
||||
@ -460,14 +267,6 @@ _get_empty_array_position_(struct qb_poll_source *s)
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
#ifndef HAVE_EPOLL
|
||||
new_size = (s->poll_entry_count + 1) * sizeof(struct pollfd);
|
||||
ufds = realloc(s->ufds, new_size);
|
||||
if (ufds == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
s->ufds = ufds;
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
s->poll_entry_count += 1;
|
||||
install_pos = s->poll_entry_count - 1;
|
||||
@ -484,9 +283,6 @@ _poll_add_(struct qb_loop *l,
|
||||
uint32_t install_pos;
|
||||
int32_t res = 0;
|
||||
struct qb_poll_source *s;
|
||||
#ifdef HAVE_EPOLL
|
||||
struct epoll_event ev;
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
@ -507,17 +303,14 @@ _poll_add_(struct qb_loop *l,
|
||||
pe->item.source = (struct qb_loop_source *)l->fd_source;
|
||||
pe->p = p;
|
||||
pe->runs = 0;
|
||||
#ifdef HAVE_EPOLL
|
||||
ev.events = _poll_to_epoll_event_(events);
|
||||
ev.data.u64 = (((uint64_t) (pe->check)) << 32) | pe->install_pos;
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "epoll_ctl(add)");
|
||||
res = s->driver.add(s, pe, fd, events);
|
||||
if (res == 0) {
|
||||
*pe_pt = pe;
|
||||
return 0;
|
||||
} else {
|
||||
pe->state = QB_POLL_ENTRY_EMPTY;
|
||||
return res;
|
||||
}
|
||||
#endif /* HAVE_EPOLL */
|
||||
*pe_pt = pe;
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
@ -548,6 +341,11 @@ qb_loop_poll_add(struct qb_loop * lp,
|
||||
|
||||
size = ((struct qb_poll_source *)l->fd_source)->poll_entry_count;
|
||||
res = _poll_add_(l, p, fd, events, data, &pe);
|
||||
if (res != 0) {
|
||||
qb_util_perror(LOG_ERR,
|
||||
"couldn't add poll entryfor FD %d", fd);
|
||||
return res;
|
||||
}
|
||||
new_size = ((struct qb_poll_source *)l->fd_source)->poll_entry_count;
|
||||
|
||||
pe->poll_dispatch_fn = dispatch_fn;
|
||||
@ -573,9 +371,6 @@ qb_loop_poll_mod(struct qb_loop * lp,
|
||||
int32_t res = 0;
|
||||
struct qb_poll_entry *pe;
|
||||
struct qb_poll_source *s;
|
||||
#ifdef HAVE_EPOLL
|
||||
struct epoll_event ev;
|
||||
#endif /* HAVE_EPOLL */
|
||||
struct qb_loop *l = lp;
|
||||
|
||||
if (l == NULL) {
|
||||
@ -600,14 +395,7 @@ qb_loop_poll_mod(struct qb_loop * lp,
|
||||
pe->item.user_data = data;
|
||||
pe->p = p;
|
||||
if (pe->ufd.events != events) {
|
||||
#ifdef HAVE_EPOLL
|
||||
ev.events = _poll_to_epoll_event_(events);
|
||||
ev.data.u64 = (((uint64_t) (pe->check)) << 32) | i;
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_MOD, fd, &ev) == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "epoll_ctl(mod)");
|
||||
}
|
||||
#endif /* HAVE_EPOLL */
|
||||
res = s->driver.mod(s, pe, fd, events);
|
||||
pe->ufd.events = events;
|
||||
}
|
||||
return res;
|
||||
@ -641,16 +429,7 @@ qb_loop_poll_del(struct qb_loop * lp, int32_t fd)
|
||||
if (pe->state == QB_POLL_ENTRY_JOBLIST) {
|
||||
qb_loop_level_item_del(&l->level[pe->p], &pe->item);
|
||||
}
|
||||
#ifdef HAVE_EPOLL
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_WARNING, "epoll_ctl(del)");
|
||||
}
|
||||
#else
|
||||
s->ufds[i].fd = -1;
|
||||
s->ufds[i].events = 0;
|
||||
s->ufds[i].revents = 0;
|
||||
#endif /* HAVE_EPOLL */
|
||||
res = s->driver.del(s, pe, fd, i);
|
||||
_poll_entry_mark_deleted_(pe);
|
||||
return res;
|
||||
}
|
||||
|
||||
209
lib/loop_poll_epoll.c
Normal file
209
lib/loop_poll_epoll.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* Author: Angus Salkeld <asalkeld@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os_base.h"
|
||||
#include "loop_poll_int.h"
|
||||
|
||||
#ifdef HAVE_SYS_EPOLL_H
|
||||
#include <sys/epoll.h>
|
||||
#ifndef epoll_create1
|
||||
int epoll_create1(int flags);
|
||||
#endif /* workaround a set of sparc and alpha broken headers */
|
||||
#endif /* HAVE_SYS_EPOLL_H */
|
||||
|
||||
#define MAX_EVENTS 12
|
||||
|
||||
static int32_t
|
||||
_poll_to_epoll_event_(int32_t event)
|
||||
{
|
||||
int32_t out = 0;
|
||||
if (event & POLLIN)
|
||||
out |= EPOLLIN;
|
||||
if (event & POLLOUT)
|
||||
out |= EPOLLOUT;
|
||||
if (event & POLLPRI)
|
||||
out |= EPOLLPRI;
|
||||
if (event & POLLERR)
|
||||
out |= EPOLLERR;
|
||||
if (event & POLLHUP)
|
||||
out |= EPOLLHUP;
|
||||
if (event & POLLNVAL)
|
||||
out |= EPOLLERR;
|
||||
return out;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_epoll_to_poll_event_(int32_t event)
|
||||
{
|
||||
int32_t out = 0;
|
||||
if (event & EPOLLIN)
|
||||
out |= POLLIN;
|
||||
if (event & EPOLLOUT)
|
||||
out |= POLLOUT;
|
||||
if (event & EPOLLPRI)
|
||||
out |= POLLPRI;
|
||||
if (event & EPOLLERR)
|
||||
out |= POLLERR;
|
||||
if (event & EPOLLHUP)
|
||||
out |= POLLHUP;
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
_fini(struct qb_poll_source *s)
|
||||
{
|
||||
if (s->epollfd != -1) {
|
||||
close(s->epollfd);
|
||||
s->epollfd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_add(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
int32_t res = 0;
|
||||
|
||||
ev.events = _poll_to_epoll_event_(events);
|
||||
ev.data.u64 = (((uint64_t) (pe->check)) << 32) | pe->install_pos;
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "epoll_ctl(add)");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int32_t
|
||||
_mod(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
int32_t res = 0;
|
||||
|
||||
ev.events = _poll_to_epoll_event_(events);
|
||||
ev.data.u64 = (((uint64_t) (pe->check)) << 32) | pe->install_pos;
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_MOD, fd, &ev) == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_DEBUG, "epoll_ctl(mod)");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_del(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t arr_index)
|
||||
{
|
||||
int32_t res = 0;
|
||||
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_DEBUG, "epoll_ctl(del)");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_poll_entry_from_handle_(struct qb_poll_source *s,
|
||||
uint64_t handle_in, struct qb_poll_entry **pe_pt)
|
||||
{
|
||||
int32_t res = 0;
|
||||
uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32));
|
||||
uint32_t handle = handle_in & 0xffffffff;
|
||||
struct qb_poll_entry *pe;
|
||||
|
||||
res = qb_array_index(s->poll_entries, handle, (void **)&pe);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
if (pe->check != check) {
|
||||
return -EINVAL;
|
||||
}
|
||||
*pe_pt = pe;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t res;
|
||||
int32_t event_count;
|
||||
int32_t new_jobs = 0;
|
||||
struct qb_poll_entry *pe = NULL;
|
||||
struct qb_poll_source *s = (struct qb_poll_source *)src;
|
||||
struct epoll_event events[MAX_EVENTS];
|
||||
|
||||
qb_poll_fds_usage_check_(s);
|
||||
|
||||
retry_poll:
|
||||
|
||||
event_count = epoll_wait(s->epollfd, events, MAX_EVENTS, ms_timeout);
|
||||
|
||||
if (errno == EINTR && event_count == -1) {
|
||||
goto retry_poll;
|
||||
} else if (event_count == -1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
for (i = 0; i < event_count; i++) {
|
||||
res = _poll_entry_from_handle_(s, events[i].data.u64, &pe);
|
||||
if (res != 0) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"can't find poll entry for new event.");
|
||||
continue;
|
||||
}
|
||||
if (pe->ufd.fd == -1 || pe->state == QB_POLL_ENTRY_DELETED) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"can't post new event to a deleted entry.");
|
||||
/*
|
||||
* empty/deleted
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (events[i].events == pe->ufd.revents ||
|
||||
pe->state == QB_POLL_ENTRY_JOBLIST) {
|
||||
/*
|
||||
* entry already in the job queue.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
pe->ufd.revents = _epoll_to_poll_event_(events[i].events);
|
||||
|
||||
new_jobs += pe->add_to_jobs(src->l, pe);
|
||||
}
|
||||
|
||||
return new_jobs;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_epoll_init(struct qb_poll_source *s)
|
||||
{
|
||||
s->epollfd = epoll_create1(EPOLL_CLOEXEC);
|
||||
if (s->epollfd < 0) {
|
||||
return -errno;
|
||||
}
|
||||
s->driver.fini = _fini;
|
||||
s->driver.add = _add;
|
||||
s->driver.mod = _mod;
|
||||
s->driver.del = _del;
|
||||
s->s.poll = _poll_and_add_to_jobs_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
91
lib/loop_poll_int.h
Normal file
91
lib/loop_poll_int.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* Author: Angus Salkeld <asalkeld@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef QB_LOOP_POLL_INT_DEFINED
|
||||
#define QB_LOOP_POLL_INT_DEFINED
|
||||
|
||||
#include "os_base.h"
|
||||
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif /* HAVE_SYS_POLL_H */
|
||||
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qblist.h>
|
||||
#include <qb/qbarray.h>
|
||||
#include <qb/qbutil.h>
|
||||
|
||||
#include "loop_int.h"
|
||||
#include "util_int.h"
|
||||
|
||||
struct qb_poll_entry;
|
||||
|
||||
typedef int32_t(*qb_poll_add_to_jobs_fn) (struct qb_loop * l,
|
||||
struct qb_poll_entry * pe);
|
||||
|
||||
struct qb_poll_entry {
|
||||
struct qb_loop_item item;
|
||||
qb_loop_poll_dispatch_fn poll_dispatch_fn;
|
||||
enum qb_loop_priority p;
|
||||
uint32_t install_pos;
|
||||
struct pollfd ufd;
|
||||
qb_poll_add_to_jobs_fn add_to_jobs;
|
||||
uint32_t runs;
|
||||
enum qb_poll_entry_state state;
|
||||
uint32_t check;
|
||||
};
|
||||
|
||||
struct qb_poll_source;
|
||||
|
||||
struct qb_loop_driver {
|
||||
int32_t (*poll)(struct qb_loop_source* s, int32_t ms_timeout);
|
||||
void (*fini)(struct qb_poll_source *s);
|
||||
int32_t (*add)(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events);
|
||||
int32_t (*mod)(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events);
|
||||
int32_t (*del)(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t arr_index);
|
||||
};
|
||||
|
||||
struct qb_poll_source {
|
||||
struct qb_loop_source s;
|
||||
int32_t poll_entry_count;
|
||||
qb_array_t *poll_entries;
|
||||
qb_loop_poll_low_fds_event_fn low_fds_event_fn;
|
||||
int32_t not_enough_fds;
|
||||
#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE)
|
||||
int32_t epollfd;
|
||||
#else
|
||||
struct pollfd *ufds;
|
||||
#endif /* HAVE_EPOLL */
|
||||
struct qb_loop_driver driver;
|
||||
};
|
||||
|
||||
void
|
||||
qb_poll_fds_usage_check_(struct qb_poll_source *s);
|
||||
|
||||
int32_t
|
||||
qb_epoll_init(struct qb_poll_source *s);
|
||||
|
||||
int32_t
|
||||
qb_poll_init(struct qb_poll_source *s);
|
||||
|
||||
int32_t
|
||||
qb_kqueue_init(struct qb_poll_source *s);
|
||||
|
||||
#endif /* QB_LOOP_POLL_INT_DEFINED */
|
||||
210
lib/loop_poll_kqueue.c
Normal file
210
lib/loop_poll_kqueue.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* Author: Angus Salkeld <asalkeld@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os_base.h"
|
||||
#include "loop_poll_int.h"
|
||||
|
||||
#ifdef HAVE_SYS_EVENT_H
|
||||
#include <sys/event.h>
|
||||
#endif /* HAVE_SYS_EVENT_H */
|
||||
|
||||
#define MAX_EVENTS 12
|
||||
|
||||
static int32_t
|
||||
_poll_to_filter_(int32_t event)
|
||||
{
|
||||
int32_t out = 0;
|
||||
if (event & POLLIN)
|
||||
out |= EVFILT_READ;
|
||||
if (event & POLLOUT)
|
||||
out |= EVFILT_WRITE;
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
_fini(struct qb_poll_source *s)
|
||||
{
|
||||
if (s->epollfd != -1) {
|
||||
close(s->epollfd);
|
||||
s->epollfd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_add(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events)
|
||||
{
|
||||
int32_t res = 0;
|
||||
struct kevent ke;
|
||||
short filters = _poll_to_filter_(events);
|
||||
|
||||
EV_SET(&ke, fd, filters, EV_ADD, 0, 0, (intptr_t)pe);
|
||||
|
||||
res = kevent(s->epollfd, &ke, 1, NULL, 0, NULL);
|
||||
if (res == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "kevent(add)");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_mod(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events)
|
||||
{
|
||||
int32_t res = 0;
|
||||
struct kevent ke[2];
|
||||
short new_filters = _poll_to_filter_(events);
|
||||
short old_filters = _poll_to_filter_(pe->ufd.events);
|
||||
|
||||
EV_SET(&ke[0], fd, old_filters, EV_DELETE, 0, 0, (intptr_t)pe);
|
||||
EV_SET(&ke[1], fd, new_filters, EV_ADD, 0, 0, (intptr_t)pe);
|
||||
|
||||
res = kevent(s->epollfd, ke, 2, NULL, 0, NULL);
|
||||
if (res == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "kevent(mod)");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_del(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events)
|
||||
{
|
||||
int32_t res = 0;
|
||||
struct kevent ke;
|
||||
short filters = _poll_to_filter_(events);
|
||||
|
||||
EV_SET(&ke, fd, filters, EV_DELETE, 0, 0, (intptr_t)pe);
|
||||
|
||||
res = kevent(s->epollfd, &ke, 1, NULL, 0, NULL);
|
||||
if (res == -1 && errno == ENOENT) {
|
||||
/*
|
||||
* Not a problem already cleaned up.
|
||||
*/
|
||||
res = 0;
|
||||
} else if (res == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "kevent(del)");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t event_count;
|
||||
int32_t new_jobs = 0;
|
||||
int32_t revents = 0;
|
||||
struct qb_poll_entry *pe = NULL;
|
||||
struct qb_poll_source *s = (struct qb_poll_source *)src;
|
||||
struct kevent events[MAX_EVENTS];
|
||||
struct timespec timeout = { 0, 0 };
|
||||
struct timespec *timeout_pt = &timeout;
|
||||
|
||||
if (ms_timeout > 0) {
|
||||
qb_timespec_add_ms(&timeout, ms_timeout);
|
||||
} else if (ms_timeout < 0) {
|
||||
timeout_pt = NULL;
|
||||
}
|
||||
qb_poll_fds_usage_check_(s);
|
||||
|
||||
retry_poll:
|
||||
|
||||
event_count = kevent(s->epollfd, NULL, 0, events, MAX_EVENTS, timeout_pt);
|
||||
if (errno == EINTR && event_count == -1) {
|
||||
goto retry_poll;
|
||||
} else if (event_count == -1) {
|
||||
qb_util_perror(LOG_ERR, "kevent(poll)");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
for (i = 0; i < event_count; i++) {
|
||||
revents = 0;
|
||||
pe = (struct qb_poll_entry *)events[i].udata;
|
||||
if (events[i].flags) {
|
||||
qb_util_log(LOG_TRACE,
|
||||
"got flags %d on fd %d.", events[i].flags,
|
||||
pe->ufd.fd);
|
||||
}
|
||||
if (events[i].flags & EV_ERROR) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"got EV_ERROR on fd %d.", pe->ufd.fd);
|
||||
revents |= POLLERR;
|
||||
}
|
||||
if (events[i].flags & EV_EOF) {
|
||||
qb_util_log(LOG_INFO,
|
||||
"got EV_EOF on fd %d.", pe->ufd.fd);
|
||||
revents |= POLLHUP;
|
||||
}
|
||||
if (events[i].filter == EVFILT_READ) {
|
||||
revents |= POLLIN;
|
||||
}
|
||||
if (events[i].filter == EVFILT_WRITE) {
|
||||
revents |= POLLOUT;
|
||||
}
|
||||
if (pe->ufd.fd == -1 || pe->state == QB_POLL_ENTRY_DELETED) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"can't post new event to a deleted entry.");
|
||||
/*
|
||||
* empty/deleted
|
||||
*/
|
||||
EV_SET(&events[i], events[i].ident, events[i].filter,
|
||||
EV_DELETE, 0, 0, (intptr_t)pe);
|
||||
(void)kevent(s->epollfd, &events[i], 1, NULL, 0, NULL);
|
||||
continue;
|
||||
}
|
||||
if (pe->ufd.fd != events[i].ident) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"can't find poll entry for new event.");
|
||||
continue;
|
||||
}
|
||||
if (revents == pe->ufd.revents ||
|
||||
pe->state == QB_POLL_ENTRY_JOBLIST) {
|
||||
/*
|
||||
* entry already in the job queue.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
pe->ufd.revents = revents;
|
||||
|
||||
new_jobs += pe->add_to_jobs(src->l, pe);
|
||||
}
|
||||
|
||||
return new_jobs;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_kqueue_init(struct qb_poll_source *s)
|
||||
{
|
||||
s->epollfd = kqueue();
|
||||
|
||||
if (s->epollfd < 0) {
|
||||
qb_util_perror(LOG_ERR, "kqueue()");
|
||||
return -errno;
|
||||
}
|
||||
s->driver.fini = _fini;
|
||||
s->driver.add = _add;
|
||||
s->driver.mod = _mod;
|
||||
s->driver.del = _del;
|
||||
s->s.poll = _poll_and_add_to_jobs_;
|
||||
return 0;
|
||||
}
|
||||
109
lib/loop_poll_poll.c
Normal file
109
lib/loop_poll_poll.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* Author: Angus Salkeld <asalkeld@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "os_base.h"
|
||||
|
||||
#include "loop_poll_int.h"
|
||||
|
||||
|
||||
static void
|
||||
_fini(struct qb_poll_source *s)
|
||||
{
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_add(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_mod(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_del(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t i)
|
||||
{
|
||||
s->ufds[i].fd = -1;
|
||||
s->ufds[i].events = 0;
|
||||
s->ufds[i].revents = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t res;
|
||||
int32_t new_jobs = 0;
|
||||
struct qb_poll_entry *pe;
|
||||
struct qb_poll_source *s = (struct qb_poll_source *)src;
|
||||
|
||||
qb_poll_fds_usage_check_(s);
|
||||
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0);
|
||||
memcpy(&s->ufds[i], &pe->ufd, sizeof(struct pollfd));
|
||||
}
|
||||
|
||||
retry_poll:
|
||||
res = poll(s->ufds, s->poll_entry_count, ms_timeout);
|
||||
if (errno == EINTR && res == -1) {
|
||||
goto retry_poll;
|
||||
} else if (res == -1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
if (s->ufds[i].fd == -1 || s->ufds[i].revents == 0) {
|
||||
/*
|
||||
* empty entry
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0);
|
||||
if (pe->state != QB_POLL_ENTRY_ACTIVE ||
|
||||
s->ufds[i].revents == pe->ufd.revents) {
|
||||
/*
|
||||
* Wrong state to accept an event.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
pe->ufd.revents = s->ufds[i].revents;
|
||||
new_jobs += pe->add_to_jobs(src->l, pe);
|
||||
}
|
||||
|
||||
return new_jobs;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_poll_init(struct qb_poll_source *s)
|
||||
{
|
||||
s->ufds = 0;
|
||||
s->driver.fini = _fini;
|
||||
s->driver.add = _add;
|
||||
s->driver.mod = _mod;
|
||||
s->driver.del = _del;
|
||||
s->s.poll = _poll_and_add_to_jobs_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
326
lib/ringbuffer.c
326
lib/ringbuffer.c
@ -34,6 +34,35 @@ do { \
|
||||
#define DEBUG_PRINTF(format, args...)
|
||||
#endif /* CRAZY_DEBUG_PRINTFS */
|
||||
|
||||
/*
|
||||
* move the write pointer to the next 128 byte boundary
|
||||
* write_pt goes in 4 bytes (sizeof(uint32_t))
|
||||
* #define USE_CACHE_LINE_ALIGNMENT 1
|
||||
*/
|
||||
#ifdef USE_CACHE_LINE_ALIGNMENT
|
||||
#define QB_CACHE_LINE_SIZE 128
|
||||
#define QB_CACHE_LINE_WORDS (QB_CACHE_LINE_SIZE/sizeof(uint32_t))
|
||||
#define idx_cache_line_step(idx) \
|
||||
do { \
|
||||
if (idx % QB_CACHE_LINE_WORDS) { \
|
||||
idx += (QB_CACHE_LINE_WORDS - (idx % QB_CACHE_LINE_WORDS)); \
|
||||
} \
|
||||
if (idx > (rb->shared_hdr->word_size - 1)) { \
|
||||
idx = ((idx) % (rb->shared_hdr->word_size)); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define QB_CACHE_LINE_SIZE 0
|
||||
#define QB_CACHE_LINE_WORDS 0
|
||||
#define idx_cache_line_step(idx) \
|
||||
do { \
|
||||
if (idx > (rb->shared_hdr->word_size - 1)) { \
|
||||
idx = ((idx) % (rb->shared_hdr->word_size)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/* the chunk header is two words
|
||||
* 1) the chunk data size
|
||||
* 2) the magic number
|
||||
@ -46,16 +75,31 @@ do { \
|
||||
* So:
|
||||
* qb_rb_space_free() >= QB_RB_CHUNK_MARGIN + new data chunk
|
||||
* The extra word size is to allow for non word sized data chunks.
|
||||
* QB_CACHE_LINE_WORDS is to make sure we have space to align the
|
||||
* chunk.
|
||||
*/
|
||||
#define QB_RB_CHUNK_MARGIN (sizeof(uint32_t) * (QB_RB_CHUNK_HEADER_WORDS + 1))
|
||||
#define QB_RB_CHUNK_MAGIC 0xAAAAAAAA
|
||||
#define QB_RB_WORD_ALIGN 1
|
||||
#define QB_RB_CHUNK_MARGIN (sizeof(uint32_t) * (QB_RB_CHUNK_HEADER_WORDS +\
|
||||
QB_RB_WORD_ALIGN +\
|
||||
QB_CACHE_LINE_WORDS))
|
||||
#define QB_RB_CHUNK_MAGIC 0xA1A1A1A1
|
||||
#define QB_RB_CHUNK_MAGIC_DEAD 0xD0D0D0D0
|
||||
#define QB_RB_CHUNK_MAGIC_ALLOC 0xA110CED0
|
||||
#define QB_RB_CHUNK_SIZE_GET(rb, pointer) \
|
||||
rb->shared_data[pointer]
|
||||
#define QB_RB_CHUNK_MAGIC_GET(rb, pointer) \
|
||||
rb->shared_data[(pointer + 1) % rb->shared_hdr->word_size]
|
||||
#define QB_RB_CHUNK_MAGIC_SET(rb, pointer, new_val) \
|
||||
rb->shared_data[(pointer + 1) % rb->shared_hdr->word_size] = new_val;
|
||||
#define QB_RB_CHUNK_DATA_GET(rb, pointer) \
|
||||
&rb->shared_data[(pointer + QB_RB_CHUNK_HEADER_WORDS) % rb->shared_hdr->word_size]
|
||||
|
||||
#define QB_RB_WRITE_PT_INDEX (rb->shared_hdr->word_size)
|
||||
#define QB_RB_READ_PT_INDEX (rb->shared_hdr->word_size + 1)
|
||||
#define QB_MAGIC_ASSERT(_ptr_) \
|
||||
do { \
|
||||
uint32_t chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, _ptr_); \
|
||||
if (chunk_magic != QB_RB_CHUNK_MAGIC) print_header(rb); \
|
||||
assert(chunk_magic == QB_RB_CHUNK_MAGIC); \
|
||||
} while (0)
|
||||
|
||||
#define idx_step(idx) \
|
||||
do { \
|
||||
@ -64,33 +108,8 @@ do { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* move the write pointer to the next 32 byte boundary
|
||||
* write_pt goes in 4 bytes (sizeof(uint32_t))
|
||||
*/
|
||||
/*
|
||||
* #define USE_CACHE_LINE_ALIGNMENT 1
|
||||
*/
|
||||
#ifdef USE_CACHE_LINE_ALIGNMENT
|
||||
#define idx_cache_line_step(idx) \
|
||||
do { \
|
||||
if (idx % 8) { \
|
||||
idx += (8 - (idx % 8)); \
|
||||
} \
|
||||
if (idx > (rb->shared_hdr->word_size - 1)) { \
|
||||
idx = ((idx) % (rb->shared_hdr->word_size)); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define idx_cache_line_step(idx) \
|
||||
do { \
|
||||
if (idx > (rb->shared_hdr->word_size - 1)) { \
|
||||
idx = ((idx) % (rb->shared_hdr->word_size)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static void qb_rb_chunk_check(struct qb_ringbuffer_s * rb, uint32_t pointer);
|
||||
static void print_header(struct qb_ringbuffer_s * rb);
|
||||
static void _rb_chunk_reclaim(struct qb_ringbuffer_s * rb);
|
||||
|
||||
qb_ringbuffer_t *
|
||||
qb_rb_open(const char *name, size_t size, uint32_t flags,
|
||||
@ -221,7 +240,9 @@ cleanup_hdr:
|
||||
}
|
||||
if (rb && (flags & QB_RB_FLAG_CREATE)) {
|
||||
unlink(rb->shared_hdr->hdr_path);
|
||||
(void)rb->sem_destroy_fn(rb);
|
||||
if (rb->sem_destroy_fn) {
|
||||
(void)rb->sem_destroy_fn(rb);
|
||||
}
|
||||
}
|
||||
if (rb && (rb->shared_hdr != MAP_FAILED && rb->shared_hdr != NULL)) {
|
||||
munmap(rb->shared_hdr, sizeof(struct qb_ringbuffer_shared_s));
|
||||
@ -240,7 +261,9 @@ qb_rb_close(struct qb_ringbuffer_s * rb)
|
||||
|
||||
(void)qb_atomic_int_dec_and_test(&rb->shared_hdr->ref_count);
|
||||
if (rb->flags & QB_RB_FLAG_CREATE) {
|
||||
(void)rb->sem_destroy_fn(rb);
|
||||
if (rb->sem_destroy_fn) {
|
||||
(void)rb->sem_destroy_fn(rb);
|
||||
}
|
||||
unlink(rb->shared_hdr->data_path);
|
||||
unlink(rb->shared_hdr->hdr_path);
|
||||
qb_util_log(LOG_DEBUG,
|
||||
@ -262,7 +285,9 @@ qb_rb_force_close(struct qb_ringbuffer_s * rb)
|
||||
return;
|
||||
}
|
||||
|
||||
(void)rb->sem_destroy_fn(rb);
|
||||
if (rb->sem_destroy_fn) {
|
||||
(void)rb->sem_destroy_fn(rb);
|
||||
}
|
||||
unlink(rb->shared_hdr->data_path);
|
||||
unlink(rb->shared_hdr->hdr_path);
|
||||
qb_util_log(LOG_DEBUG,
|
||||
@ -311,9 +336,6 @@ qb_rb_space_free(struct qb_ringbuffer_s * rb)
|
||||
return -EINVAL;
|
||||
}
|
||||
write_size = rb->shared_hdr->write_pt;
|
||||
/*
|
||||
* TODO idx_cache_line_step (write_size);
|
||||
*/
|
||||
read_size = rb->shared_hdr->read_pt;
|
||||
|
||||
if (write_size > read_size) {
|
||||
@ -322,7 +344,11 @@ qb_rb_space_free(struct qb_ringbuffer_s * rb)
|
||||
} else if (write_size < read_size) {
|
||||
space_free = (read_size - write_size) - 1;
|
||||
} else {
|
||||
space_free = rb->shared_hdr->word_size;
|
||||
if (rb->sem_getvalue_fn && rb->sem_getvalue_fn(rb) > 0) {
|
||||
space_free = 0;
|
||||
} else {
|
||||
space_free = rb->shared_hdr->word_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* word -> bytes */
|
||||
@ -360,7 +386,11 @@ qb_rb_chunks_used(struct qb_ringbuffer_s *rb)
|
||||
if (rb == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return rb->sem_getvalue_fn(rb);
|
||||
if (rb->sem_getvalue_fn) {
|
||||
return rb->sem_getvalue_fn(rb);
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
@ -369,6 +399,7 @@ qb_rb_chunk_alloc(struct qb_ringbuffer_s * rb, size_t len)
|
||||
uint32_t write_pt;
|
||||
|
||||
if (rb == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
@ -376,7 +407,7 @@ qb_rb_chunk_alloc(struct qb_ringbuffer_s * rb, size_t len)
|
||||
*/
|
||||
if (rb->flags & QB_RB_FLAG_OVERWRITE) {
|
||||
while (qb_rb_space_free(rb) < (len + QB_RB_CHUNK_MARGIN)) {
|
||||
qb_rb_chunk_reclaim(rb);
|
||||
_rb_chunk_reclaim(rb);
|
||||
}
|
||||
} else {
|
||||
if (qb_rb_space_free(rb) < (len + QB_RB_CHUNK_MARGIN)) {
|
||||
@ -389,15 +420,13 @@ qb_rb_chunk_alloc(struct qb_ringbuffer_s * rb, size_t len)
|
||||
/*
|
||||
* insert the chunk header
|
||||
*/
|
||||
rb->shared_data[write_pt++] = 0;
|
||||
idx_step(write_pt);
|
||||
rb->shared_data[write_pt++] = QB_RB_CHUNK_MAGIC;
|
||||
idx_step(write_pt);
|
||||
rb->shared_data[write_pt] = 0;
|
||||
QB_RB_CHUNK_MAGIC_SET(rb, write_pt, QB_RB_CHUNK_MAGIC_ALLOC);
|
||||
|
||||
/*
|
||||
* return a pointer to the beginning of the chunk data
|
||||
*/
|
||||
return (void *)&rb->shared_data[write_pt];
|
||||
return (void *)QB_RB_CHUNK_DATA_GET(rb, write_pt);
|
||||
|
||||
}
|
||||
|
||||
@ -409,14 +438,13 @@ qb_rb_chunk_step(struct qb_ringbuffer_s * rb, uint32_t pointer)
|
||||
* skip over the chunk header
|
||||
*/
|
||||
pointer += QB_RB_CHUNK_HEADER_WORDS;
|
||||
idx_step(pointer);
|
||||
|
||||
/*
|
||||
* skip over the user's data.
|
||||
*/
|
||||
pointer += (chunk_size / sizeof(uint32_t));
|
||||
/* make allowance for non-word sizes */
|
||||
if ((chunk_size % sizeof(uint32_t)) != 0) {
|
||||
if ((chunk_size % (sizeof(uint32_t) * QB_RB_WORD_ALIGN)) != 0) {
|
||||
pointer++;
|
||||
}
|
||||
|
||||
@ -437,21 +465,28 @@ qb_rb_chunk_commit(struct qb_ringbuffer_s * rb, size_t len)
|
||||
*/
|
||||
old_write_pt = rb->shared_hdr->write_pt;
|
||||
rb->shared_data[old_write_pt] = len;
|
||||
rb->shared_data[old_write_pt + 1] = QB_RB_CHUNK_MAGIC;
|
||||
|
||||
/*
|
||||
* commit the new write pointer
|
||||
*/
|
||||
rb->shared_hdr->write_pt = qb_rb_chunk_step(rb, old_write_pt);
|
||||
QB_RB_CHUNK_MAGIC_SET(rb, old_write_pt, QB_RB_CHUNK_MAGIC);
|
||||
|
||||
DEBUG_PRINTF("%s: read: %u, write: %u (was:%u)\n", __func__,
|
||||
rb->shared_hdr->read_pt, rb->shared_hdr->write_pt,
|
||||
old_write_pt);
|
||||
DEBUG_PRINTF("commit [%zd] read: %u, write: %u -> %u (%u)\n",
|
||||
(rb->sem_getvalue_fn ? rb->sem_getvalue_fn(rb) : 0),
|
||||
rb->shared_hdr->read_pt,
|
||||
old_write_pt,
|
||||
rb->shared_hdr->write_pt,
|
||||
rb->shared_hdr->word_size);
|
||||
|
||||
/*
|
||||
* post the notification to the reader
|
||||
*/
|
||||
return rb->sem_post_fn(rb);
|
||||
if (rb->sem_post_fn) {
|
||||
return rb->sem_post_fn(rb);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
@ -478,59 +513,85 @@ qb_rb_chunk_write(struct qb_ringbuffer_s * rb, const void *data, size_t len)
|
||||
return len;
|
||||
}
|
||||
|
||||
void
|
||||
qb_rb_chunk_reclaim(struct qb_ringbuffer_s * rb)
|
||||
static void
|
||||
_rb_chunk_reclaim(struct qb_ringbuffer_s * rb)
|
||||
{
|
||||
uint32_t old_read_pt;
|
||||
uint32_t new_read_pt;
|
||||
uint32_t chunk_magic;
|
||||
|
||||
if (rb == NULL || qb_rb_space_used(rb) == 0) {
|
||||
old_read_pt = rb->shared_hdr->read_pt;
|
||||
chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, old_read_pt);
|
||||
if (chunk_magic != QB_RB_CHUNK_MAGIC) {
|
||||
return;
|
||||
}
|
||||
old_read_pt = rb->shared_hdr->read_pt;
|
||||
qb_rb_chunk_check(rb, old_read_pt);
|
||||
|
||||
rb->shared_hdr->read_pt = qb_rb_chunk_step(rb, old_read_pt);
|
||||
new_read_pt = qb_rb_chunk_step(rb, old_read_pt);
|
||||
|
||||
/*
|
||||
* clear the header
|
||||
*/
|
||||
rb->shared_data[old_read_pt] = 0;
|
||||
rb->shared_data[old_read_pt + 1] = 0;
|
||||
QB_RB_CHUNK_MAGIC_SET(rb, old_read_pt, QB_RB_CHUNK_MAGIC_DEAD);
|
||||
|
||||
DEBUG_PRINTF("%s: read: %u (was:%u), write: %u\n", __func__,
|
||||
rb->shared_hdr->read_pt, old_read_pt,
|
||||
/*
|
||||
* set the new read pointer after clearing the header
|
||||
* to prevent a situation where a fast writer will write their
|
||||
* new chunk between setting the new read pointer and clearing the
|
||||
* header.
|
||||
*/
|
||||
rb->shared_hdr->read_pt = new_read_pt;
|
||||
|
||||
DEBUG_PRINTF("reclaim [%zd]: read: %u -> %u, write: %u\n",
|
||||
(rb->sem_getvalue_fn ? rb->sem_getvalue_fn(rb) : 0),
|
||||
old_read_pt,
|
||||
rb->shared_hdr->read_pt,
|
||||
rb->shared_hdr->write_pt);
|
||||
}
|
||||
|
||||
void
|
||||
qb_rb_chunk_reclaim(struct qb_ringbuffer_s * rb)
|
||||
{
|
||||
if (rb == NULL) {
|
||||
return;
|
||||
}
|
||||
_rb_chunk_reclaim(rb);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
qb_rb_chunk_peek(struct qb_ringbuffer_s * rb, void **data_out, int32_t timeout)
|
||||
{
|
||||
uint32_t read_pt;
|
||||
uint32_t chunk_size;
|
||||
uint32_t chunk_magic;
|
||||
int32_t res;
|
||||
int32_t res = 0;
|
||||
|
||||
if (rb == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
res = rb->sem_timedwait_fn(rb, timeout);
|
||||
if (rb->sem_timedwait_fn) {
|
||||
res = rb->sem_timedwait_fn(rb, timeout);
|
||||
}
|
||||
if (res < 0 && res != -EIDRM) {
|
||||
if (res != -ETIMEDOUT) {
|
||||
if (res == -ETIMEDOUT) {
|
||||
return 0;
|
||||
} else {
|
||||
errno = -res;
|
||||
qb_util_perror(LOG_ERR, "sem_timedwait");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
read_pt = rb->shared_hdr->read_pt;
|
||||
chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
|
||||
chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt);
|
||||
*data_out = &rb->shared_data[read_pt + QB_RB_CHUNK_HEADER_WORDS];
|
||||
|
||||
if (chunk_magic != QB_RB_CHUNK_MAGIC) {
|
||||
errno = ENOMSG;
|
||||
if (rb->sem_post_fn) {
|
||||
(void)rb->sem_post_fn(rb);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return chunk_size;
|
||||
}
|
||||
chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
|
||||
*data_out = QB_RB_CHUNK_DATA_GET(rb, read_pt);
|
||||
return chunk_size;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
@ -539,6 +600,7 @@ qb_rb_chunk_read(struct qb_ringbuffer_s * rb, void *data_out, size_t len,
|
||||
{
|
||||
uint32_t read_pt;
|
||||
uint32_t chunk_size;
|
||||
uint32_t chunk_magic;
|
||||
int32_t res = 0;
|
||||
|
||||
if (rb == NULL) {
|
||||
@ -554,26 +616,36 @@ qb_rb_chunk_read(struct qb_ringbuffer_s * rb, void *data_out, size_t len,
|
||||
return res;
|
||||
}
|
||||
|
||||
if (qb_rb_space_used(rb) == 0) {
|
||||
return -ENOMSG;
|
||||
read_pt = rb->shared_hdr->read_pt;
|
||||
chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt);
|
||||
|
||||
if (chunk_magic != QB_RB_CHUNK_MAGIC) {
|
||||
if (rb->sem_timedwait_fn == NULL) {
|
||||
return -ETIMEDOUT;
|
||||
} else {
|
||||
(void)rb->sem_post_fn(rb);
|
||||
#ifdef EBADMSG
|
||||
return -EBADMSG;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
read_pt = rb->shared_hdr->read_pt;
|
||||
qb_rb_chunk_check(rb, read_pt);
|
||||
chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
|
||||
|
||||
if (len < chunk_size) {
|
||||
qb_util_log(LOG_ERR,
|
||||
"trying to recv chunk of size %d but %d available",
|
||||
len, chunk_size);
|
||||
(void)rb->sem_post_fn(rb);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
;
|
||||
memcpy(data_out,
|
||||
&rb->shared_data[read_pt + QB_RB_CHUNK_HEADER_WORDS],
|
||||
QB_RB_CHUNK_DATA_GET(rb, read_pt),
|
||||
chunk_size);
|
||||
|
||||
qb_rb_chunk_reclaim(rb);
|
||||
_rb_chunk_reclaim(rb);
|
||||
|
||||
return chunk_size;
|
||||
}
|
||||
@ -596,21 +668,6 @@ print_header(struct qb_ringbuffer_s * rb)
|
||||
#endif /* S_SPLINT_S */
|
||||
}
|
||||
|
||||
static void
|
||||
qb_rb_chunk_check(struct qb_ringbuffer_s * rb, uint32_t pointer)
|
||||
{
|
||||
uint32_t chunk_size;
|
||||
uint32_t chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, pointer);
|
||||
|
||||
if (chunk_magic != QB_RB_CHUNK_MAGIC) {
|
||||
chunk_size = QB_RB_CHUNK_SIZE_GET(rb, pointer);
|
||||
printf("size: %x\n", chunk_size);
|
||||
printf("magic: %x\n", chunk_magic);
|
||||
print_header(rb);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
qb_rb_write_to_file(struct qb_ringbuffer_s * rb, int32_t fd)
|
||||
{
|
||||
@ -628,13 +685,6 @@ qb_rb_write_to_file(struct qb_ringbuffer_s * rb, int32_t fd)
|
||||
}
|
||||
written_size += result;
|
||||
|
||||
result = write(fd, rb->shared_data,
|
||||
rb->shared_hdr->word_size * sizeof(uint32_t));
|
||||
if (result != rb->shared_hdr->word_size * sizeof(uint32_t)) {
|
||||
return -errno;
|
||||
}
|
||||
written_size += result;
|
||||
|
||||
/*
|
||||
* store the read & write pointers
|
||||
*/
|
||||
@ -649,6 +699,13 @@ qb_rb_write_to_file(struct qb_ringbuffer_s * rb, int32_t fd)
|
||||
}
|
||||
written_size += result;
|
||||
|
||||
result = write(fd, rb->shared_data,
|
||||
rb->shared_hdr->word_size * sizeof(uint32_t));
|
||||
if (result != rb->shared_hdr->word_size * sizeof(uint32_t)) {
|
||||
return -errno;
|
||||
}
|
||||
written_size += result;
|
||||
|
||||
qb_util_log(LOG_DEBUG, " writing total of: %zd\n", written_size);
|
||||
|
||||
return written_size;
|
||||
@ -663,35 +720,37 @@ qb_rb_create_from_file(int32_t fd, uint32_t flags)
|
||||
uint32_t read_pt;
|
||||
uint32_t write_pt;
|
||||
struct qb_ringbuffer_s *rb;
|
||||
uint32_t word_size = 0;
|
||||
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
rb = calloc(1, sizeof(struct qb_ringbuffer_s));
|
||||
if (rb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
rb->shared_hdr = calloc(1, sizeof(struct qb_ringbuffer_shared_s));
|
||||
if (rb->shared_hdr == NULL) {
|
||||
goto cleanup_fail2;
|
||||
}
|
||||
|
||||
rb->flags = flags;
|
||||
|
||||
n_required = sizeof(uint32_t);
|
||||
n_read = read(fd, &rb->shared_hdr->word_size, n_required);
|
||||
n_read = read(fd, &word_size, n_required);
|
||||
if (n_read != n_required) {
|
||||
qb_util_perror(LOG_ERR, "Unable to read blackbox file header");
|
||||
goto cleanup_fail;
|
||||
return NULL;
|
||||
}
|
||||
total_read += n_read;
|
||||
|
||||
n_required = (rb->shared_hdr->word_size * sizeof(uint32_t));
|
||||
n_read = read(fd, &write_pt, sizeof(uint32_t));
|
||||
assert(n_read == sizeof(uint32_t));
|
||||
total_read += n_read;
|
||||
|
||||
if ((rb->shared_data = malloc(n_required)) == NULL) {
|
||||
qb_util_perror(LOG_ERR, "exhausted virtual memory");
|
||||
goto cleanup_fail;
|
||||
n_read = read(fd, &read_pt, sizeof(uint32_t));
|
||||
assert(n_read == sizeof(uint32_t));
|
||||
total_read += n_read;
|
||||
|
||||
n_required = (word_size * sizeof(uint32_t));
|
||||
rb = qb_rb_open("create_from_file", n_required,
|
||||
QB_RB_FLAG_CREATE | QB_RB_FLAG_NO_SEMAPHORE, 0);
|
||||
if (rb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
rb->shared_hdr->read_pt = read_pt;
|
||||
rb->shared_hdr->write_pt = write_pt;
|
||||
|
||||
n_read = read(fd, rb->shared_data, n_required);
|
||||
if (n_read < 0) {
|
||||
qb_util_perror(LOG_ERR, "Unable to read blackbox file data");
|
||||
@ -705,25 +764,13 @@ qb_rb_create_from_file(int32_t fd, uint32_t flags)
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
||||
n_read = read(fd, &write_pt, sizeof(uint32_t));
|
||||
assert(n_read == sizeof(uint32_t));
|
||||
rb->shared_hdr->write_pt = write_pt;
|
||||
total_read += n_read;
|
||||
|
||||
n_read = read(fd, &read_pt, sizeof(uint32_t));
|
||||
assert(n_read == sizeof(uint32_t));
|
||||
rb->shared_hdr->read_pt = read_pt;
|
||||
total_read += n_read;
|
||||
|
||||
qb_util_log(LOG_DEBUG, "read total of: %zd", total_read);
|
||||
print_header(rb);
|
||||
|
||||
return rb;
|
||||
|
||||
cleanup_fail:
|
||||
free(rb->shared_hdr);
|
||||
cleanup_fail2:
|
||||
free(rb);
|
||||
qb_rb_close(rb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -736,10 +783,29 @@ qb_rb_chown(struct qb_ringbuffer_s * rb, uid_t owner, gid_t group)
|
||||
return -EINVAL;
|
||||
}
|
||||
res = chown(rb->shared_hdr->data_path, owner, group);
|
||||
if (res < 0) {
|
||||
if (res < 0 && errno != EPERM) {
|
||||
return -errno;
|
||||
}
|
||||
res = chown(rb->shared_hdr->hdr_path, owner, group);
|
||||
if (res < 0 && errno != EPERM) {
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode)
|
||||
{
|
||||
int32_t res;
|
||||
|
||||
if (rb == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
res = chmod(rb->shared_hdr->data_path, mode);
|
||||
if (res < 0) {
|
||||
return -errno;
|
||||
}
|
||||
res = chmod(rb->shared_hdr->hdr_path, mode);
|
||||
if (res < 0) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@ -34,11 +34,11 @@ my_posix_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout)
|
||||
|
||||
sem_wait_again:
|
||||
if (ms_timeout > 0) {
|
||||
res = sem_timedwait(&rb->shared_hdr->posix_sem, &ts_timeout);
|
||||
res = rpl_sem_timedwait(&rb->shared_hdr->posix_sem, &ts_timeout);
|
||||
} else if (ms_timeout == 0) {
|
||||
res = sem_trywait(&rb->shared_hdr->posix_sem);
|
||||
res = rpl_sem_trywait(&rb->shared_hdr->posix_sem);
|
||||
} else {
|
||||
res = sem_wait(&rb->shared_hdr->posix_sem);
|
||||
res = rpl_sem_wait(&rb->shared_hdr->posix_sem);
|
||||
}
|
||||
if (res == -1) {
|
||||
switch (errno) {
|
||||
@ -63,7 +63,7 @@ sem_wait_again:
|
||||
static int32_t
|
||||
my_posix_sem_post(qb_ringbuffer_t * rb)
|
||||
{
|
||||
if (sem_post(&rb->shared_hdr->posix_sem) < 0) {
|
||||
if (rpl_sem_post(&rb->shared_hdr->posix_sem) < 0) {
|
||||
return -errno;
|
||||
} else {
|
||||
return 0;
|
||||
@ -74,7 +74,7 @@ static ssize_t
|
||||
my_posix_getvalue_fn(struct qb_ringbuffer_s *rb)
|
||||
{
|
||||
int val;
|
||||
if (sem_getvalue(&rb->shared_hdr->posix_sem, &val) < 0) {
|
||||
if (rpl_sem_getvalue(&rb->shared_hdr->posix_sem, &val) < 0) {
|
||||
return -errno;
|
||||
} else {
|
||||
return val;
|
||||
@ -84,7 +84,7 @@ my_posix_getvalue_fn(struct qb_ringbuffer_s *rb)
|
||||
static int32_t
|
||||
my_posix_sem_destroy(qb_ringbuffer_t * rb)
|
||||
{
|
||||
if (sem_destroy(&rb->shared_hdr->posix_sem) == -1) {
|
||||
if (rpl_sem_destroy(&rb->shared_hdr->posix_sem) == -1) {
|
||||
return -errno;
|
||||
} else {
|
||||
return 0;
|
||||
@ -101,20 +101,19 @@ my_posix_sem_create(struct qb_ringbuffer_s *rb, uint32_t flags)
|
||||
}
|
||||
pshared = 1;
|
||||
}
|
||||
if (sem_init(&rb->shared_hdr->posix_sem, pshared, 0) == -1) {
|
||||
if (rpl_sem_init(&rb->shared_hdr->posix_sem, pshared, 0) == -1) {
|
||||
return -errno;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HAVE_POSIX_SHARED_SEMAPHORE
|
||||
static int32_t
|
||||
my_sysv_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout)
|
||||
{
|
||||
struct sembuf sops[1];
|
||||
int32_t res = 0;
|
||||
#ifndef QB_FREEBSD_GE_8
|
||||
#ifdef HAVE_SEMTIMEDOP
|
||||
struct timespec ts_timeout;
|
||||
struct timespec *ts_pt;
|
||||
|
||||
@ -130,25 +129,25 @@ my_sysv_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout)
|
||||
} else {
|
||||
ts_pt = NULL;
|
||||
}
|
||||
#endif /* bsd */
|
||||
#endif /* HAVE_SEMTIMEDOP */
|
||||
|
||||
/*
|
||||
* wait for sem post.
|
||||
*/
|
||||
sops[0].sem_num = 0;
|
||||
sops[0].sem_op = -1;
|
||||
#ifdef QB_FREEBSD_GE_8
|
||||
sops[0].sem_flg = IPC_NOWAIT;
|
||||
#else
|
||||
#ifdef HAVE_SEMTIMEDOP
|
||||
sops[0].sem_flg = 0;
|
||||
#endif /* bsd */
|
||||
#else
|
||||
sops[0].sem_flg = IPC_NOWAIT;
|
||||
#endif /* HAVE_SEMTIMEDOP */
|
||||
|
||||
semop_again:
|
||||
#ifdef QB_FREEBSD_GE_8
|
||||
if (semop(rb->sem_id, sops, 1) == -1)
|
||||
#else
|
||||
#ifdef HAVE_SEMTIMEDOP
|
||||
if (semtimedop(rb->sem_id, sops, 1, ts_pt) == -1)
|
||||
#endif
|
||||
#else
|
||||
if (semop(rb->sem_id, sops, 1) == -1)
|
||||
#endif /* HAVE_SEMTIMEDOP */
|
||||
{
|
||||
if (errno == EINTR) {
|
||||
goto semop_again;
|
||||
@ -249,25 +248,44 @@ my_sysv_sem_create(qb_ringbuffer_t * rb, uint32_t flags)
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif /* NOT HAVE_POSIX_SHARED_SEMAPHORE */
|
||||
|
||||
int32_t
|
||||
qb_rb_sem_create(struct qb_ringbuffer_s * rb, uint32_t flags)
|
||||
{
|
||||
#ifndef HAVE_POSIX_SHARED_SEMAPHORE
|
||||
if (rb->flags & QB_RB_FLAG_SHARED_PROCESS) {
|
||||
rb->sem_timedwait_fn = my_sysv_sem_timedwait;
|
||||
rb->sem_post_fn = my_sysv_sem_post;
|
||||
rb->sem_getvalue_fn = my_sysv_getvalue_fn;
|
||||
rb->sem_destroy_fn = my_sysv_sem_destroy;
|
||||
return my_sysv_sem_create(rb, flags);
|
||||
} else
|
||||
#endif /* NOT HAVE_POSIX_SHARED_SEMAPHORE */
|
||||
{
|
||||
int32_t rc;
|
||||
int32_t use_posix = QB_TRUE;
|
||||
|
||||
if ((flags & QB_RB_FLAG_SHARED_PROCESS) &&
|
||||
!(flags & QB_RB_FLAG_NO_SEMAPHORE)) {
|
||||
#if defined(HAVE_POSIX_PSHARED_SEMAPHORE) || \
|
||||
defined(HAVE_RPL_PSHARED_SEMAPHORE)
|
||||
use_posix = QB_TRUE;
|
||||
#else
|
||||
#ifdef HAVE_SYSV_PSHARED_SEMAPHORE
|
||||
use_posix = QB_FALSE;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif /* HAVE_SYSV_PSHARED_SEMAPHORE */
|
||||
#endif /* HAVE_POSIX_PSHARED_SEMAPHORE */
|
||||
}
|
||||
if (flags & QB_RB_FLAG_NO_SEMAPHORE) {
|
||||
rc = 0;
|
||||
rb->sem_timedwait_fn = NULL;
|
||||
rb->sem_post_fn = NULL;
|
||||
rb->sem_getvalue_fn = NULL;
|
||||
rb->sem_destroy_fn = NULL;
|
||||
} else if (use_posix) {
|
||||
rc = my_posix_sem_create(rb, flags);
|
||||
rb->sem_timedwait_fn = my_posix_sem_timedwait;
|
||||
rb->sem_post_fn = my_posix_sem_post;
|
||||
rb->sem_getvalue_fn = my_posix_getvalue_fn;
|
||||
rb->sem_destroy_fn = my_posix_sem_destroy;
|
||||
return my_posix_sem_create(rb, flags);
|
||||
} else {
|
||||
rc = my_sysv_sem_create(rb, flags);
|
||||
rb->sem_timedwait_fn = my_sysv_sem_timedwait;
|
||||
rb->sem_post_fn = my_sysv_sem_post;
|
||||
rb->sem_getvalue_fn = my_sysv_getvalue_fn;
|
||||
rb->sem_destroy_fn = my_sysv_sem_destroy;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -32,9 +32,7 @@
|
||||
#ifdef HAVE_SYS_IPC_H
|
||||
#include <sys/ipc.h>
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "rpl_sem.h"
|
||||
#include "util_int.h"
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qbrb.h>
|
||||
@ -55,9 +53,9 @@ struct qb_ringbuffer_shared_s {
|
||||
char hdr_path[PATH_MAX];
|
||||
char data_path[PATH_MAX];
|
||||
int32_t ref_count;
|
||||
sem_t posix_sem;
|
||||
rpl_sem_t posix_sem;
|
||||
char user_data[1];
|
||||
};
|
||||
} __attribute__ ((aligned(8)));
|
||||
|
||||
struct qb_ringbuffer_s {
|
||||
uint32_t flags;
|
||||
@ -74,13 +72,13 @@ struct qb_ringbuffer_s {
|
||||
|
||||
void qb_rb_force_close(qb_ringbuffer_t * rb);
|
||||
|
||||
#if defined(_SEM_SEMUN_UNDEFINED)
|
||||
#ifndef HAVE_SEMUN
|
||||
union semun {
|
||||
int32_t val;
|
||||
struct semid_ds *buf;
|
||||
unsigned short int *array;
|
||||
struct seminfo *__buf;
|
||||
};
|
||||
#endif /* _SEM_SEMUN_UNDEFINED */
|
||||
#endif /* HAVE_SEMUN */
|
||||
|
||||
#endif /* _RINGBUFFER_H_ */
|
||||
|
||||
190
lib/rpl_sem.c
Normal file
190
lib/rpl_sem.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Pingtel Corp., certain elements licensed under a Contributor Agreement.
|
||||
* Contributors retain copyright to elements licensed under a Contributor Agreement.
|
||||
* Licensed to the User under the LGPL license.
|
||||
*
|
||||
* Modified by: Angus Salkeld <asalkeld@redhat.com>
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
* To conform to posix API and support process shared semaphores.
|
||||
*
|
||||
* The bsd posix semaphore implementation does not have support for timing
|
||||
* out while waiting for a synchronization object. This uses the
|
||||
* pthread_cond_timedwait function and a mutex to build all the other
|
||||
* synchronization objecs with timeout capabilities.
|
||||
*/
|
||||
|
||||
#include "os_base.h"
|
||||
#include <pthread.h>
|
||||
#include "rpl_sem.h"
|
||||
|
||||
int
|
||||
rpl_sem_init(rpl_sem_t * sem, int pshared, unsigned int count)
|
||||
{
|
||||
int rc;
|
||||
pthread_mutexattr_t mattr;
|
||||
pthread_condattr_t cattr;
|
||||
|
||||
#ifndef HAVE_RPL_PSHARED_SEMAPHORE
|
||||
if (pshared) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
#endif /* HAVE_RPL_PSHARED_SEMAPHORE */
|
||||
sem->count = count;
|
||||
|
||||
(void)pthread_mutexattr_init(&mattr);
|
||||
(void)pthread_condattr_init(&cattr);
|
||||
#ifdef HAVE_RPL_PSHARED_SEMAPHORE
|
||||
if (pshared) {
|
||||
rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
|
||||
if (rc != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
rc = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
|
||||
if (rc != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_RPL_PSHARED_SEMAPHORE */
|
||||
rc = pthread_mutex_init(&sem->mutex, &mattr);
|
||||
if (rc != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
rc = pthread_cond_init(&sem->cond, &cattr);
|
||||
|
||||
if (rc != 0) {
|
||||
goto cleanup_mutex;
|
||||
}
|
||||
return 0;
|
||||
|
||||
cleanup_mutex:
|
||||
pthread_mutex_destroy(&sem->mutex);
|
||||
|
||||
cleanup:
|
||||
pthread_mutexattr_destroy(&mattr);
|
||||
pthread_condattr_destroy(&cattr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
rpl_sem_wait(rpl_sem_t * sem)
|
||||
{
|
||||
int retval = pthread_mutex_lock(&sem->mutex);
|
||||
if (retval != 0) {
|
||||
errno = retval;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* wait for sem->count to be not zero, or error
|
||||
*/
|
||||
while (retval == 0 && !sem->count) {
|
||||
retval = pthread_cond_wait(&sem->cond, &sem->mutex);
|
||||
}
|
||||
switch (retval) {
|
||||
case 0:
|
||||
/* retval is 0 and sem->count is not, the sem is ours
|
||||
*/
|
||||
sem->count--;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = retval;
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
rpl_sem_timedwait(rpl_sem_t * sem, const struct timespec *timeout)
|
||||
{
|
||||
int retval = pthread_mutex_lock(&sem->mutex);
|
||||
if (retval != 0) {
|
||||
errno = retval;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* wait for sem->count to be not zero, or error
|
||||
*/
|
||||
while (0 == retval && !sem->count) {
|
||||
retval = pthread_cond_timedwait(&sem->cond, &sem->mutex, timeout);
|
||||
}
|
||||
|
||||
switch (retval) {
|
||||
case 0:
|
||||
/* retval is 0 and sem->count is not, the sem is ours
|
||||
*/
|
||||
sem->count--;
|
||||
break;
|
||||
|
||||
case ETIMEDOUT:
|
||||
/* timedout waiting for count to be not zero
|
||||
*/
|
||||
errno = EAGAIN;
|
||||
retval = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = retval;
|
||||
retval = -1;
|
||||
}
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
rpl_sem_trywait(rpl_sem_t * sem)
|
||||
{
|
||||
int retval = pthread_mutex_lock(&sem->mutex);
|
||||
if (retval != 0) {
|
||||
errno = retval;
|
||||
return -1;
|
||||
}
|
||||
if (sem->count) {
|
||||
sem->count--;
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return 0;
|
||||
}
|
||||
errno = EAGAIN;
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
rpl_sem_post(rpl_sem_t * sem)
|
||||
{
|
||||
int retval = pthread_mutex_lock(&sem->mutex);
|
||||
if (retval != 0) {
|
||||
errno = retval;
|
||||
return -1;
|
||||
}
|
||||
sem->count++;
|
||||
retval = pthread_cond_broadcast(&sem->cond);
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
if (retval != 0) {
|
||||
errno = retval;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rpl_sem_getvalue(rpl_sem_t * sem, int *sval)
|
||||
{
|
||||
int retval = pthread_mutex_lock(&sem->mutex);
|
||||
if (retval != 0) {
|
||||
errno = retval;
|
||||
return -1;
|
||||
}
|
||||
*sval = sem->count;
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rpl_sem_destroy(rpl_sem_t * sem)
|
||||
{
|
||||
return pthread_mutex_destroy(&sem->mutex) |
|
||||
pthread_cond_destroy(&sem->cond);
|
||||
}
|
||||
64
lib/rpl_sem.h
Normal file
64
lib/rpl_sem.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Pingtel Corp., certain elements licensed under a Contributor Agreement.
|
||||
* Contributors retain copyright to elements licensed under a Contributor Agreement.
|
||||
* Licensed to the User under the LGPL license.
|
||||
*
|
||||
* Modified by: Angus Salkeld <asalkeld@redhat.com>
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
* To conform to official implementation and support process shared semaphores.
|
||||
*
|
||||
* The bsd posix semaphore implementation does not have support for timing
|
||||
* out while waiting for a synchronization object. This uses the
|
||||
* pthread_cond_timedwait function and a mutex to build all the other
|
||||
* synchronization objecs with timeout capabilities.
|
||||
*/
|
||||
|
||||
#ifndef _RPL_SEM_H
|
||||
#define _RPL_SEM_H
|
||||
|
||||
#include "os_base.h"
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SEM_TIMEDWAIT
|
||||
#define rpl_sem_t sem_t
|
||||
#define rpl_sem_init sem_init
|
||||
#define rpl_sem_wait sem_wait
|
||||
#define rpl_sem_timedwait sem_timedwait
|
||||
#define rpl_sem_post sem_post
|
||||
#define rpl_sem_getvalue sem_getvalue
|
||||
#define rpl_sem_destroy sem_destroy
|
||||
#define rpl_sem_trywait sem_trywait
|
||||
#else
|
||||
|
||||
typedef struct rpl_sem {
|
||||
unsigned int count;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
} rpl_sem_t;
|
||||
|
||||
int rpl_sem_init(rpl_sem_t * sem, int pshared, unsigned int count);
|
||||
|
||||
int rpl_sem_wait(rpl_sem_t *sem);
|
||||
|
||||
int rpl_sem_timedwait(rpl_sem_t *sem,const struct timespec *timeout);
|
||||
|
||||
int rpl_sem_trywait(rpl_sem_t *sem);
|
||||
|
||||
int rpl_sem_post(rpl_sem_t *sem);
|
||||
|
||||
int rpl_sem_getvalue(rpl_sem_t * sem, int *sval);
|
||||
|
||||
int rpl_sem_destroy(rpl_sem_t *sem);
|
||||
|
||||
#endif /* HAVE_SEM_TIMEDWAIT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RPL_SEM_H */
|
||||
25
lib/unix.c
25
lib/unix.c
@ -32,17 +32,25 @@
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qbatomic.h>
|
||||
|
||||
#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS)
|
||||
/*
|
||||
* BSD derivatives usually have MAP_ANON, not MAP_ANONYMOUS
|
||||
**/
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
|
||||
char *
|
||||
qb_strerror_r(int errnum, char *buf, size_t buflen)
|
||||
{
|
||||
#ifdef QB_LINUX
|
||||
#ifdef STRERROR_R_CHAR_P
|
||||
return strerror_r(errnum, buf, buflen);
|
||||
#else
|
||||
if (strerror_r(errnum, buf, buflen) != 0) {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
return buf;
|
||||
#endif /* QB_LINUX */
|
||||
#endif /* STRERROR_R_CHAR_P */
|
||||
}
|
||||
|
||||
static int32_t
|
||||
@ -72,7 +80,12 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes,
|
||||
if (is_absolute) {
|
||||
(void)strlcpy(path, file, PATH_MAX);
|
||||
} else {
|
||||
#if defined(QB_LINUX) || defined(QB_CYGWIN)
|
||||
snprintf(path, PATH_MAX, "/dev/shm/%s", file);
|
||||
#else
|
||||
snprintf(path, PATH_MAX, LOCALSTATEDIR "/run/%s", file);
|
||||
is_absolute = path;
|
||||
#endif
|
||||
}
|
||||
fd = open_mmap_file(path, file_flags);
|
||||
if (fd < 0 && !is_absolute) {
|
||||
@ -85,6 +98,10 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes,
|
||||
qb_util_perror(LOG_ERR, "couldn't open file %s", path);
|
||||
return res;
|
||||
}
|
||||
} else if (fd < 0 && is_absolute) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "couldn't open file %s", path);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (ftruncate(fd, bytes) == -1) {
|
||||
@ -165,7 +182,7 @@ qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes)
|
||||
res = -errno;
|
||||
goto cleanup_fail;
|
||||
}
|
||||
#ifdef QB_BSD
|
||||
#if defined(QB_BSD) && defined(MADV_NOSYNC)
|
||||
madvise(addr_orig, bytes, MADV_NOSYNC);
|
||||
#endif
|
||||
addr_next = ((char *)addr_orig) + bytes;
|
||||
@ -176,7 +193,7 @@ qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes)
|
||||
res = -errno;
|
||||
goto cleanup_fail;
|
||||
}
|
||||
#ifdef QB_BSD
|
||||
#if defined(QB_BSD) && defined(MADV_NOSYNC)
|
||||
madvise(((char *)addr_orig) + bytes, bytes, MADV_NOSYNC);
|
||||
#endif
|
||||
|
||||
|
||||
@ -197,7 +197,7 @@ qb_util_nano_current_get(void)
|
||||
uint64_t
|
||||
qb_util_nano_monotonic_hz(void)
|
||||
{
|
||||
return HZ;
|
||||
return sysconf(_SC_CLK_TCK);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -34,7 +34,7 @@ make check
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
||||
rm -rf $RPM_BUILD_ROOT/%{_docdir}/*
|
||||
rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc/libqb
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
@ -46,6 +46,7 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc COPYING
|
||||
%{_sbindir}/qb-blackbox
|
||||
%{_libdir}/libqb.so.*
|
||||
|
||||
%package devel
|
||||
@ -64,6 +65,7 @@ developing applications that use %{name}.
|
||||
%{_libdir}/libqb.so
|
||||
%{_libdir}/pkgconfig/libqb.pc
|
||||
%{_mandir}/man3/qb*3*
|
||||
%{_mandir}/man8/qb-blackbox.8.gz
|
||||
|
||||
%changelog
|
||||
* @date@ Autotools generated version <nobody@nowhere.org> - @version@-1-@numcomm@.@alphatag@.@dirty@
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
MAINTAINERCLEANFILES = Makefiles.in
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
EXTRA_DIST =
|
||||
CLEANFILES =
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
@ -31,23 +31,23 @@ noinst_PROGRAMS = bmc bmcpt bms rbwriter rbreader loop bench-log \
|
||||
|
||||
|
||||
bmc_SOURCES = bmc.c $(top_builddir)/include/qb/qbipcc.h
|
||||
bmc_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
bmc_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
bmcpt_SOURCES = bmcpt.c $(top_builddir)/include/qb/qbipcc.h
|
||||
bmcpt_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
bmcpt_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
bms_SOURCES = bms.c $(top_builddir)/include/qb/qbipcs.h
|
||||
bms_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include $(GLIB_CFLAGS)
|
||||
bms_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
bms_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
|
||||
rbwriter_SOURCES = rbwriter.c $(top_builddir)/include/qb/qbrb.h
|
||||
rbwriter_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
rbwriter_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
rbreader_SOURCES = rbreader.c $(top_builddir)/include/qb/qbrb.h
|
||||
rbreader_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
rbreader_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
loop_SOURCES = loop.c $(top_builddir)/include/qb/qbloop.h
|
||||
loop_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
loop_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
public_headers = $(wildcard $(top_srcdir)/include/qb/qb*.h)
|
||||
auto_c_files = $(patsubst %.h,auto_check_header_%.c,$(public_headers))
|
||||
@ -84,7 +84,7 @@ endif
|
||||
|
||||
bench_log_SOURCES = bench-log.c $(top_builddir)/include/qb/qblog.h
|
||||
bench_log_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
bench_log_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
bench_log_LDADD = $(top_builddir)/lib/libqb.la
|
||||
|
||||
if HAVE_CHECK
|
||||
EXTRA_DIST += resources.test
|
||||
@ -103,31 +103,31 @@ endif
|
||||
|
||||
array_test_SOURCES = check_array.c $(top_builddir)/include/qb/qbarray.h
|
||||
array_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
array_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
array_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
|
||||
map_test_SOURCES = check_map.c $(top_builddir)/include/qb/qbmap.h
|
||||
map_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
map_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
map_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
|
||||
rb_test_SOURCES = check_rb.c $(top_builddir)/include/qb/qbrb.h
|
||||
rb_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
rb_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
rb_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
|
||||
loop_test_SOURCES = check_loop.c $(top_builddir)/include/qb/qbloop.h
|
||||
loop_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
loop_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
loop_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
|
||||
ipc_test_SOURCES = check_ipc.c $(top_builddir)/include/qb/qbipcc.h $(top_builddir)/include/qb/qbipcs.h
|
||||
ipc_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
ipc_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
ipc_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
|
||||
log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h
|
||||
log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
log_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
log_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
|
||||
util_test_SOURCES = check_util.c $(top_builddir)/include/qb/qbutil.h
|
||||
util_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
util_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
util_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
|
||||
endif
|
||||
|
||||
|
||||
@ -87,10 +87,8 @@ am__array_test_SOURCES_DIST = check_array.c \
|
||||
@HAVE_CHECK_TRUE@am_array_test_OBJECTS = \
|
||||
@HAVE_CHECK_TRUE@ array_test-check_array.$(OBJEXT)
|
||||
array_test_OBJECTS = $(am_array_test_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
@HAVE_CHECK_TRUE@array_test_DEPENDENCIES = \
|
||||
@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la \
|
||||
@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1)
|
||||
@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
@ -148,26 +146,23 @@ am_bench_log_OBJECTS = bench_log-bench-log.$(OBJEXT)
|
||||
@HAVE_DICT_WORDS_TRUE@@HAVE_SLOW_TESTS_TRUE@nodist_bench_log_OBJECTS = bench_log-auto_write_logs.$(OBJEXT)
|
||||
bench_log_OBJECTS = $(am_bench_log_OBJECTS) \
|
||||
$(nodist_bench_log_OBJECTS)
|
||||
bench_log_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
bench_log_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am_bmc_OBJECTS = bmc.$(OBJEXT)
|
||||
bmc_OBJECTS = $(am_bmc_OBJECTS)
|
||||
bmc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(top_builddir)/lib/libqb.la
|
||||
bmc_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am_bmcpt_OBJECTS = bmcpt.$(OBJEXT)
|
||||
bmcpt_OBJECTS = $(am_bmcpt_OBJECTS)
|
||||
bmcpt_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
bmcpt_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am_bms_OBJECTS = bms-bms.$(OBJEXT)
|
||||
bms_OBJECTS = $(am_bms_OBJECTS)
|
||||
bms_DEPENDENCIES = $(am__DEPENDENCIES_1) $(top_builddir)/lib/libqb.la \
|
||||
$(am__DEPENDENCIES_1)
|
||||
am__DEPENDENCIES_1 =
|
||||
bms_DEPENDENCIES = $(top_builddir)/lib/libqb.la $(am__DEPENDENCIES_1)
|
||||
am__ipc_test_SOURCES_DIST = check_ipc.c \
|
||||
$(top_builddir)/include/qb/qbipcc.h \
|
||||
$(top_builddir)/include/qb/qbipcs.h
|
||||
@HAVE_CHECK_TRUE@am_ipc_test_OBJECTS = ipc_test-check_ipc.$(OBJEXT)
|
||||
ipc_test_OBJECTS = $(am_ipc_test_OBJECTS)
|
||||
@HAVE_CHECK_TRUE@ipc_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \
|
||||
@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1)
|
||||
@HAVE_CHECK_TRUE@ipc_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
ipc_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ipc_test_CFLAGS) \
|
||||
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
@ -175,22 +170,20 @@ am__log_test_SOURCES_DIST = check_log.c \
|
||||
$(top_builddir)/include/qb/qblog.h
|
||||
@HAVE_CHECK_TRUE@am_log_test_OBJECTS = log_test-check_log.$(OBJEXT)
|
||||
log_test_OBJECTS = $(am_log_test_OBJECTS)
|
||||
@HAVE_CHECK_TRUE@log_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \
|
||||
@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1)
|
||||
@HAVE_CHECK_TRUE@log_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
log_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(log_test_CFLAGS) \
|
||||
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
am_loop_OBJECTS = loop.$(OBJEXT)
|
||||
loop_OBJECTS = $(am_loop_OBJECTS)
|
||||
loop_DEPENDENCIES = $(am__DEPENDENCIES_1) $(top_builddir)/lib/libqb.la
|
||||
loop_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am__loop_test_SOURCES_DIST = check_loop.c \
|
||||
$(top_builddir)/include/qb/qbloop.h
|
||||
@HAVE_CHECK_TRUE@am_loop_test_OBJECTS = \
|
||||
@HAVE_CHECK_TRUE@ loop_test-check_loop.$(OBJEXT)
|
||||
loop_test_OBJECTS = $(am_loop_test_OBJECTS)
|
||||
@HAVE_CHECK_TRUE@loop_test_DEPENDENCIES = \
|
||||
@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la \
|
||||
@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1)
|
||||
@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la
|
||||
loop_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(loop_test_CFLAGS) \
|
||||
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
@ -198,8 +191,7 @@ am__map_test_SOURCES_DIST = check_map.c \
|
||||
$(top_builddir)/include/qb/qbmap.h
|
||||
@HAVE_CHECK_TRUE@am_map_test_OBJECTS = map_test-check_map.$(OBJEXT)
|
||||
map_test_OBJECTS = $(am_map_test_OBJECTS)
|
||||
@HAVE_CHECK_TRUE@map_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \
|
||||
@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1)
|
||||
@HAVE_CHECK_TRUE@map_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
map_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(map_test_CFLAGS) \
|
||||
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
@ -207,32 +199,28 @@ am__rb_test_SOURCES_DIST = check_rb.c \
|
||||
$(top_builddir)/include/qb/qbrb.h
|
||||
@HAVE_CHECK_TRUE@am_rb_test_OBJECTS = rb_test-check_rb.$(OBJEXT)
|
||||
rb_test_OBJECTS = $(am_rb_test_OBJECTS)
|
||||
@HAVE_CHECK_TRUE@rb_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \
|
||||
@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1)
|
||||
@HAVE_CHECK_TRUE@rb_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
rb_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(rb_test_CFLAGS) \
|
||||
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
am_rbreader_OBJECTS = rbreader.$(OBJEXT)
|
||||
rbreader_OBJECTS = $(am_rbreader_OBJECTS)
|
||||
rbreader_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
rbreader_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am_rbwriter_OBJECTS = rbwriter.$(OBJEXT)
|
||||
rbwriter_OBJECTS = $(am_rbwriter_OBJECTS)
|
||||
rbwriter_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(top_builddir)/lib/libqb.la
|
||||
rbwriter_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
am__util_test_SOURCES_DIST = check_util.c \
|
||||
$(top_builddir)/include/qb/qbutil.h
|
||||
@HAVE_CHECK_TRUE@am_util_test_OBJECTS = \
|
||||
@HAVE_CHECK_TRUE@ util_test-check_util.$(OBJEXT)
|
||||
util_test_OBJECTS = $(am_util_test_OBJECTS)
|
||||
@HAVE_CHECK_TRUE@util_test_DEPENDENCIES = \
|
||||
@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la \
|
||||
@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1)
|
||||
@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la
|
||||
util_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(util_test_CFLAGS) \
|
||||
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
@ -286,132 +274,8 @@ DIST_SOURCES = $(am__array_test_SOURCES_DIST) \
|
||||
$(rbwriter_SOURCES) $(am__util_test_SOURCES_DIST)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
# If stdout is a non-dumb tty, use colors. If test -t is not supported,
|
||||
# then this fails; a conservative approach. Of course do not redirect
|
||||
# stdout here, just stderr.
|
||||
am__tty_colors = \
|
||||
red=; grn=; lgn=; blu=; std=; \
|
||||
test "X$(AM_COLOR_TESTS)" != Xno \
|
||||
&& test "X$$TERM" != Xdumb \
|
||||
&& { test "X$(AM_COLOR_TESTS)" = Xalways || test -t 1 2>/dev/null; } \
|
||||
&& { \
|
||||
red='[0;31m'; \
|
||||
grn='[0;32m'; \
|
||||
lgn='[1;32m'; \
|
||||
blu='[1;34m'; \
|
||||
std='[m'; \
|
||||
}
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
# Restructured Text title and section.
|
||||
am__rst_title = sed 's/.*/ & /;h;s/./=/g;p;x;p;g;p;s/.*//'
|
||||
am__rst_section = sed 'p;s/./=/g;p;g'
|
||||
# Put stdin (possibly several lines separated by ". ") in a box.
|
||||
# Prefix each line by 'col' and terminate each with 'std', for coloring.
|
||||
# Multi line coloring is problematic with "less -R", so we really need
|
||||
# to color each line individually.
|
||||
am__text_box = $(AWK) '{ \
|
||||
n = split($$0, lines, "\\. "); max = 0; \
|
||||
for (i = 1; i <= n; ++i) \
|
||||
if (max < length(lines[i])) \
|
||||
max = length(lines[i]); \
|
||||
for (i = 0; i < max; ++i) \
|
||||
line = line "="; \
|
||||
print col line std; \
|
||||
for (i = 1; i <= n; ++i) \
|
||||
if (lines[i]) \
|
||||
print col lines[i] std; \
|
||||
print col line std; \
|
||||
}'
|
||||
# Solaris 10 'make', and several other traditional 'make' implementations,
|
||||
# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
|
||||
# by disabling -e (using the XSI extension "set +e") if it's set.
|
||||
am__sh_e_setup = case $$- in *e*) set +e;; esac
|
||||
# To be inserted before the command running the test. Creates the
|
||||
# directory for the log if needed. Stores in $dir the directory
|
||||
# containing $f, in $tst the test, in $log the log, and passes
|
||||
# TESTS_ENVIRONMENT. Save and restore TERM around use of
|
||||
# TESTS_ENVIRONMENT, in case that unsets it.
|
||||
am__check_pre = \
|
||||
$(am__sh_e_setup); \
|
||||
$(am__vpath_adj_setup) $(am__vpath_adj) \
|
||||
srcdir=$(srcdir); export srcdir; \
|
||||
rm -f $@-t; \
|
||||
am__trap='rm -f '\''$(abs_builddir)/$@-t'\''; (exit $$st); exit $$st'; \
|
||||
trap "st=129; $$am__trap" 1; trap "st=130; $$am__trap" 2; \
|
||||
trap "st=141; $$am__trap" 13; trap "st=143; $$am__trap" 15; \
|
||||
am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`; \
|
||||
test "x$$am__odir" = x. || $(MKDIR_P) "$$am__odir" || exit $$?; \
|
||||
if test -f "./$$f"; then dir=./; \
|
||||
elif test -f "$$f"; then dir=; \
|
||||
else dir="$(srcdir)/"; fi; \
|
||||
tst=$$dir$$f; log='$@'; __SAVED_TERM=$$TERM; \
|
||||
$(TESTS_ENVIRONMENT)
|
||||
# To be appended to the command running the test. Handle the stdout
|
||||
# and stderr redirection, and catch the exit status.
|
||||
am__check_post = \
|
||||
>$@-t 2>&1; \
|
||||
estatus=$$?; \
|
||||
if test -n '$(DISABLE_HARD_ERRORS)' \
|
||||
&& test $$estatus -eq 99; then \
|
||||
estatus=1; \
|
||||
fi; \
|
||||
TERM=$$__SAVED_TERM; export TERM; \
|
||||
$(am__tty_colors); \
|
||||
xfailed=PASS; \
|
||||
case " $(XFAIL_TESTS) " in \
|
||||
*[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
|
||||
xfailed=XFAIL;; \
|
||||
esac; \
|
||||
case $$estatus.$$xfailed in \
|
||||
0.XFAIL) col=$$red; res=XPASS;; \
|
||||
0.*) col=$$grn; res=PASS ;; \
|
||||
77.*) col=$$blu; res=SKIP ;; \
|
||||
99.*) col=$$red; res=FAIL ;; \
|
||||
*.XFAIL) col=$$lgn; res=XFAIL;; \
|
||||
*.*) col=$$red; res=FAIL ;; \
|
||||
esac; \
|
||||
echo "$${col}$$res$${std}: $$f"; \
|
||||
echo "$$res: $$f (exit: $$estatus)" | \
|
||||
$(am__rst_section) >$@; \
|
||||
cat $@-t >>$@; \
|
||||
rm -f $@-t
|
||||
RECHECK_LOGS = $(TEST_LOGS)
|
||||
AM_RECURSIVE_TARGETS = check recheck check-html recheck-html
|
||||
TEST_SUITE_HTML = $(TEST_SUITE_LOG:.log=.html)
|
||||
TEST_SUITE_LOG = test-suite.log
|
||||
TEST_EXTENSIONS = @EXEEXT@ .test
|
||||
am__test_logs1 = $(TESTS:=.log)
|
||||
am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
|
||||
TEST_LOGS = $(am__test_logs2:.test.log=.log)
|
||||
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
|
||||
$(TEST_LOG_FLAGS)
|
||||
TEST_LOGS_TMP = $(TEST_LOGS:.log=.log-t)
|
||||
red=; grn=; lgn=; blu=; std=
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
@ -459,7 +323,6 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_RT = @LIB_RT@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
@ -566,55 +429,55 @@ top_srcdir = @top_srcdir@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
MAINTAINERCLEANFILES = Makefiles.in $(auto_c_files) $(am__append_3)
|
||||
MAINTAINERCLEANFILES = Makefile.in $(auto_c_files) $(am__append_3)
|
||||
EXTRA_DIST = $(am__append_1) $(am__append_4)
|
||||
CLEANFILES = $(auto_c_files) $(am__append_2)
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
bmc_SOURCES = bmc.c $(top_builddir)/include/qb/qbipcc.h
|
||||
bmc_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
bmc_LDADD = $(top_builddir)/lib/libqb.la
|
||||
bmcpt_SOURCES = bmcpt.c $(top_builddir)/include/qb/qbipcc.h
|
||||
bmcpt_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
bmcpt_LDADD = $(top_builddir)/lib/libqb.la
|
||||
bms_SOURCES = bms.c $(top_builddir)/include/qb/qbipcs.h
|
||||
bms_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include $(GLIB_CFLAGS)
|
||||
bms_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
bms_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
|
||||
rbwriter_SOURCES = rbwriter.c $(top_builddir)/include/qb/qbrb.h
|
||||
rbwriter_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
rbwriter_LDADD = $(top_builddir)/lib/libqb.la
|
||||
rbreader_SOURCES = rbreader.c $(top_builddir)/include/qb/qbrb.h
|
||||
rbreader_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
rbreader_LDADD = $(top_builddir)/lib/libqb.la
|
||||
loop_SOURCES = loop.c $(top_builddir)/include/qb/qbloop.h
|
||||
loop_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
loop_LDADD = $(top_builddir)/lib/libqb.la
|
||||
public_headers = $(wildcard $(top_srcdir)/include/qb/qb*.h)
|
||||
auto_c_files = $(patsubst %.h,auto_check_header_%.c,$(public_headers))
|
||||
@HAVE_DICT_WORDS_TRUE@@HAVE_SLOW_TESTS_TRUE@nodist_bench_log_SOURCES = auto_write_logs.c
|
||||
bench_log_SOURCES = bench-log.c $(top_builddir)/include/qb/qblog.h
|
||||
bench_log_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
bench_log_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
|
||||
bench_log_LDADD = $(top_builddir)/lib/libqb.la
|
||||
@HAVE_CHECK_TRUE@check_SCRIPTS = resources.test
|
||||
@HAVE_CHECK_TRUE@array_test_SOURCES = check_array.c $(top_builddir)/include/qb/qbarray.h
|
||||
@HAVE_CHECK_TRUE@array_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
@HAVE_CHECK_TRUE@array_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@array_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@map_test_SOURCES = check_map.c $(top_builddir)/include/qb/qbmap.h
|
||||
@HAVE_CHECK_TRUE@map_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
@HAVE_CHECK_TRUE@map_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@map_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@rb_test_SOURCES = check_rb.c $(top_builddir)/include/qb/qbrb.h
|
||||
@HAVE_CHECK_TRUE@rb_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
@HAVE_CHECK_TRUE@rb_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@rb_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@loop_test_SOURCES = check_loop.c $(top_builddir)/include/qb/qbloop.h
|
||||
@HAVE_CHECK_TRUE@loop_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
@HAVE_CHECK_TRUE@loop_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@loop_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@ipc_test_SOURCES = check_ipc.c $(top_builddir)/include/qb/qbipcc.h $(top_builddir)/include/qb/qbipcs.h
|
||||
@HAVE_CHECK_TRUE@ipc_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
@HAVE_CHECK_TRUE@ipc_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@ipc_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h
|
||||
@HAVE_CHECK_TRUE@log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
@HAVE_CHECK_TRUE@log_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@log_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@util_test_SOURCES = check_util.c $(top_builddir)/include/qb/qbutil.h
|
||||
@HAVE_CHECK_TRUE@util_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
@HAVE_CHECK_TRUE@util_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
|
||||
@HAVE_CHECK_TRUE@util_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .html .lo .log .o .obj .test .test$(EXEEXT)
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
@ -1000,137 +863,98 @@ GTAGS:
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
$(TEST_SUITE_LOG): $(TEST_LOGS)
|
||||
@$(am__sh_e_setup); \
|
||||
list='$(TEST_LOGS)'; \
|
||||
results=`for f in $$list; do \
|
||||
test -r $$f && read line < $$f && echo "$$line" \
|
||||
|| echo FAIL; \
|
||||
done`; \
|
||||
all=`echo "$$results" | sed '/^$$/d' | wc -l | sed -e 's/^[ ]*//'`; \
|
||||
fail=`echo "$$results" | grep -c '^FAIL'`; \
|
||||
pass=`echo "$$results" | grep -c '^PASS'`; \
|
||||
skip=`echo "$$results" | grep -c '^SKIP'`; \
|
||||
xfail=`echo "$$results" | grep -c '^XFAIL'`; \
|
||||
xpass=`echo "$$results" | grep -c '^XPASS'`; \
|
||||
failures=`expr $$fail + $$xpass`; \
|
||||
all=`expr $$all - $$skip`; \
|
||||
if test "$$all" -eq 1; then tests=test; All=; \
|
||||
else tests=tests; All="All "; fi; \
|
||||
case fail=$$fail:xpass=$$xpass:xfail=$$xfail in \
|
||||
fail=0:xpass=0:xfail=0) \
|
||||
msg="$$All$$all $$tests passed. "; \
|
||||
exit=true;; \
|
||||
fail=0:xpass=0:xfail=*) \
|
||||
msg="$$All$$all $$tests behaved as expected"; \
|
||||
if test "$$xfail" -eq 1; then xfailures=failure; \
|
||||
else xfailures=failures; fi; \
|
||||
msg="$$msg ($$xfail expected $$xfailures). "; \
|
||||
exit=true;; \
|
||||
fail=*:xpass=0:xfail=*) \
|
||||
msg="$$fail of $$all $$tests failed. "; \
|
||||
exit=false;; \
|
||||
fail=*:xpass=*:xfail=*) \
|
||||
msg="$$failures of $$all $$tests did not behave as expected"; \
|
||||
if test "$$xpass" -eq 1; then xpasses=pass; \
|
||||
else xpasses=passes; fi; \
|
||||
msg="$$msg ($$xpass unexpected $$xpasses). "; \
|
||||
exit=false;; \
|
||||
*) \
|
||||
echo >&2 "incorrect case"; exit 4;; \
|
||||
esac; \
|
||||
if test "$$skip" -ne 0; then \
|
||||
if test "$$skip" -eq 1; then \
|
||||
msg="$$msg($$skip test was not run). "; \
|
||||
else \
|
||||
msg="$$msg($$skip tests were not run). "; \
|
||||
fi; \
|
||||
fi; \
|
||||
{ \
|
||||
echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
|
||||
$(am__rst_title); \
|
||||
echo "$$msg"; \
|
||||
echo; \
|
||||
echo ".. contents:: :depth: 2"; \
|
||||
echo; \
|
||||
for f in $$list; do \
|
||||
test -r $$f && read line < $$f || line=; \
|
||||
case $$line in \
|
||||
PASS:*|XFAIL:*);; \
|
||||
*) echo; cat $$f;; \
|
||||
esac; \
|
||||
done; \
|
||||
} >$(TEST_SUITE_LOG).tmp; \
|
||||
mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
|
||||
if test "$$failures" -ne 0; then \
|
||||
msg="$${msg}See $(subdir)/$(TEST_SUITE_LOG). "; \
|
||||
if test -n "$(PACKAGE_BUGREPORT)"; then \
|
||||
msg="$${msg}Please report to $(PACKAGE_BUGREPORT). "; \
|
||||
fi; \
|
||||
fi; \
|
||||
test x"$$VERBOSE" = x || $$exit || cat $(TEST_SUITE_LOG); \
|
||||
$(am__tty_colors); \
|
||||
if $$exit; then \
|
||||
col="$$grn"; \
|
||||
else \
|
||||
col="$$red"; \
|
||||
fi; \
|
||||
echo "$$msg" | $(am__text_box) "col=$$col" "std=$$std"; \
|
||||
$$exit || exit 1
|
||||
|
||||
check-TESTS recheck:
|
||||
@if test $@ != recheck; then \
|
||||
list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list; \
|
||||
fi
|
||||
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
|
||||
@list='' list2='$(TEST_LOGS)'; for f in $$list2; do \
|
||||
test .log = $$f && continue; \
|
||||
if test $@ = recheck; then \
|
||||
test -f $$f || continue; \
|
||||
if test -r $$f && read line < $$f; then \
|
||||
case $$line in FAIL*|XPASS*) : ;; *) continue;; esac; \
|
||||
check-TESTS: $(TESTS)
|
||||
@failed=0; all=0; xfail=0; xpass=0; skip=0; \
|
||||
srcdir=$(srcdir); export srcdir; \
|
||||
list=' $(TESTS) '; \
|
||||
$(am__tty_colors); \
|
||||
if test -n "$$list"; then \
|
||||
for tst in $$list; do \
|
||||
if test -f ./$$tst; then dir=./; \
|
||||
elif test -f $$tst; then dir=; \
|
||||
else dir="$(srcdir)/"; fi; \
|
||||
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
|
||||
all=`expr $$all + 1`; \
|
||||
case " $(XFAIL_TESTS) " in \
|
||||
*[\ \ ]$$tst[\ \ ]*) \
|
||||
xpass=`expr $$xpass + 1`; \
|
||||
failed=`expr $$failed + 1`; \
|
||||
col=$$red; res=XPASS; \
|
||||
;; \
|
||||
*) \
|
||||
col=$$grn; res=PASS; \
|
||||
;; \
|
||||
esac; \
|
||||
elif test $$? -ne 77; then \
|
||||
all=`expr $$all + 1`; \
|
||||
case " $(XFAIL_TESTS) " in \
|
||||
*[\ \ ]$$tst[\ \ ]*) \
|
||||
xfail=`expr $$xfail + 1`; \
|
||||
col=$$lgn; res=XFAIL; \
|
||||
;; \
|
||||
*) \
|
||||
failed=`expr $$failed + 1`; \
|
||||
col=$$red; res=FAIL; \
|
||||
;; \
|
||||
esac; \
|
||||
else \
|
||||
skip=`expr $$skip + 1`; \
|
||||
col=$$blu; res=SKIP; \
|
||||
fi; \
|
||||
echo "$${col}$$res$${std}: $$tst"; \
|
||||
done; \
|
||||
if test "$$all" -eq 1; then \
|
||||
tests="test"; \
|
||||
All=""; \
|
||||
else \
|
||||
tests="tests"; \
|
||||
All="All "; \
|
||||
fi; \
|
||||
if test "$$failed" -eq 0; then \
|
||||
if test "$$xfail" -eq 0; then \
|
||||
banner="$$All$$all $$tests passed"; \
|
||||
else \
|
||||
if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
|
||||
banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
|
||||
fi; \
|
||||
else \
|
||||
if test "$$xpass" -eq 0; then \
|
||||
banner="$$failed of $$all $$tests failed"; \
|
||||
else \
|
||||
if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
|
||||
banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
|
||||
fi; \
|
||||
fi; \
|
||||
if test -z "$$list"; then list=$$f; else list="$$list $$f"; fi; \
|
||||
done; \
|
||||
if test $@ = recheck && test -n "$$list"; then \
|
||||
echo "am--clean: ; rm -f $$list" \
|
||||
| $(MAKE) $(AM_MAKEFLAGS) -f - am--clean || exit 1; \
|
||||
fi; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$list"
|
||||
recheck: $(check_PROGRAMS) $(check_SCRIPTS)
|
||||
|
||||
am--mostlyclean-test-html:
|
||||
list='$(TEST_LOGS:.log=.html)'; test -z "$$list" || rm -f $$list
|
||||
rm -f $(TEST_SUITE_HTML)
|
||||
|
||||
.log.html:
|
||||
@list='$(RST2HTML) $$RST2HTML rst2html rst2html.py'; \
|
||||
for r2h in $$list; do \
|
||||
if ($$r2h --version) >/dev/null 2>&1; then \
|
||||
R2H=$$r2h; \
|
||||
fi; \
|
||||
done; \
|
||||
if test -z "$$R2H"; then \
|
||||
echo >&2 "cannot find rst2html, cannot create $@"; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
$$R2H $< >$@.tmp
|
||||
@mv $@.tmp $@
|
||||
|
||||
# Be sure to run check first, and then to convert the result.
|
||||
# Beware of concurrent executions. Run "check" not "check-TESTS", as
|
||||
# check-SCRIPTS and other dependencies are rebuilt by the former only.
|
||||
# And expect check to fail.
|
||||
check-html recheck-html:
|
||||
@target=`echo $@ | sed 's/-html$$//'`; \
|
||||
rv=0; $(MAKE) $(AM_MAKEFLAGS) $$target || rv=$$?; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_HTML) TEST_LOGS= || exit 4; \
|
||||
exit $$rv
|
||||
.test.log:
|
||||
@p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
@am__EXEEXT_TRUE@.test$(EXEEXT).log:
|
||||
@am__EXEEXT_TRUE@ @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
dashes="$$banner"; \
|
||||
skipped=""; \
|
||||
if test "$$skip" -ne 0; then \
|
||||
if test "$$skip" -eq 1; then \
|
||||
skipped="($$skip test was not run)"; \
|
||||
else \
|
||||
skipped="($$skip tests were not run)"; \
|
||||
fi; \
|
||||
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
|
||||
dashes="$$skipped"; \
|
||||
fi; \
|
||||
report=""; \
|
||||
if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
|
||||
report="Please report to $(PACKAGE_BUGREPORT)"; \
|
||||
test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
|
||||
dashes="$$report"; \
|
||||
fi; \
|
||||
dashes=`echo "$$dashes" | sed s/./=/g`; \
|
||||
if test "$$failed" -eq 0; then \
|
||||
col="$$grn"; \
|
||||
else \
|
||||
col="$$red"; \
|
||||
fi; \
|
||||
echo "$${col}$$dashes$${std}"; \
|
||||
echo "$${col}$$banner$${std}"; \
|
||||
test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
|
||||
test -z "$$report" || echo "$${col}$$report$${std}"; \
|
||||
echo "$${col}$$dashes$${std}"; \
|
||||
test "$$failed" -eq 0; \
|
||||
else :; fi
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
@ -1188,9 +1012,6 @@ install-strip:
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
|
||||
-test -z "$(TEST_LOGS_TMP)" || rm -f $(TEST_LOGS_TMP)
|
||||
-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
@ -1258,8 +1079,8 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: am--mostlyclean-test-html mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
@ -1271,22 +1092,21 @@ ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: check-am check-html install-am install-strip recheck-html
|
||||
.MAKE: check-am install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am am--mostlyclean-test-html check \
|
||||
check-TESTS check-am check-html clean clean-checkPROGRAMS \
|
||||
clean-generic clean-libtool clean-noinstPROGRAMS ctags \
|
||||
distclean distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
|
||||
clean-checkPROGRAMS clean-generic clean-libtool \
|
||||
clean-noinstPROGRAMS ctags distclean distclean-compile \
|
||||
distclean-generic distclean-libtool distclean-tags distdir dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
recheck recheck-html tags uninstall uninstall-am
|
||||
tags uninstall uninstall-am
|
||||
|
||||
|
||||
$(builddir)/auto_check_header_%.c: $(top_srcdir)/include/qb/%.h
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qbipcc.h>
|
||||
|
||||
#define ITERATIONS 10000000
|
||||
@ -38,43 +39,31 @@
|
||||
|
||||
struct bm_ctx {
|
||||
qb_ipcc_connection_t *conn;
|
||||
struct timeval tv1;
|
||||
struct timeval tv2;
|
||||
struct timeval tv_elapsed;
|
||||
qb_util_stopwatch_t *sw;
|
||||
float mbs;
|
||||
float secs;
|
||||
int32_t multi;
|
||||
uint32_t counter;
|
||||
};
|
||||
|
||||
#define timersub(a, b, result) \
|
||||
do { \
|
||||
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
||||
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
|
||||
if ((result)->tv_usec < 0) { \
|
||||
--(result)->tv_sec; \
|
||||
(result)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void bm_start(struct bm_ctx *ctx)
|
||||
{
|
||||
gettimeofday(&ctx->tv1, NULL);
|
||||
qb_util_stopwatch_start(ctx->sw);
|
||||
}
|
||||
|
||||
static void bm_finish(struct bm_ctx *ctx, const char *operation, int32_t size)
|
||||
{
|
||||
gettimeofday(&ctx->tv2, NULL);
|
||||
timersub(&ctx->tv2, &ctx->tv1, &ctx->tv_elapsed);
|
||||
qb_util_stopwatch_stop(ctx->sw);
|
||||
ctx->secs = qb_util_stopwatch_sec_elapsed_get(ctx->sw);
|
||||
|
||||
ctx->mbs =
|
||||
((((float)ctx->counter) * size) /
|
||||
(((float)ctx->tv_elapsed.tv_sec) +
|
||||
(((float)ctx->tv_elapsed.tv_usec) / 1000000.0))) / (1024.0 *
|
||||
1024.0);
|
||||
((((float)ctx->counter) * size) / ctx->secs) / (1024.0 *
|
||||
1024.0);
|
||||
}
|
||||
|
||||
static void bmc_connect(struct bm_ctx *ctx)
|
||||
{
|
||||
ctx->sw = qb_util_stopwatch_create();
|
||||
ctx->conn = qb_ipcc_connect("bm1", QB_MAX(1000 * (100 + THREADS),
|
||||
1024*1024));
|
||||
if (ctx->conn == NULL) {
|
||||
@ -86,6 +75,7 @@ static void bmc_connect(struct bm_ctx *ctx)
|
||||
static void bmc_disconnect(struct bm_ctx *ctx)
|
||||
{
|
||||
qb_ipcc_disconnect(ctx->conn);
|
||||
qb_util_stopwatch_free(ctx->sw);
|
||||
}
|
||||
|
||||
struct my_req {
|
||||
|
||||
@ -283,15 +283,9 @@ int32_t main(int32_t argc, char *argv[])
|
||||
case 'm':
|
||||
ipc_type = QB_IPC_SHM;
|
||||
break;
|
||||
case 's':
|
||||
ipc_type = QB_IPC_SYSV_MQ;
|
||||
break;
|
||||
case 'u':
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
break;
|
||||
case 'p':
|
||||
ipc_type = QB_IPC_POSIX_MQ;
|
||||
break;
|
||||
case 'n': /* non-blocking */
|
||||
blocking = QB_FALSE;
|
||||
break;
|
||||
|
||||
@ -21,12 +21,8 @@
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include "os_base.h"
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <check.h>
|
||||
|
||||
@ -46,8 +42,12 @@ enum my_msg_ids {
|
||||
IPC_MSG_RES_TX_RX,
|
||||
IPC_MSG_REQ_DISPATCH,
|
||||
IPC_MSG_RES_DISPATCH,
|
||||
IPC_MSG_REQ_BULK_EVENTS,
|
||||
IPC_MSG_RES_BULK_EVENTS,
|
||||
IPC_MSG_REQ_SERVER_FAIL,
|
||||
IPC_MSG_RES_SERVER_FAIL,
|
||||
IPC_MSG_REQ_SERVER_DISCONNECT,
|
||||
IPC_MSG_RES_SERVER_DISCONNECT,
|
||||
};
|
||||
|
||||
/* Test Cases
|
||||
@ -72,6 +72,9 @@ static qb_loop_t *my_loop;
|
||||
static qb_ipcs_service_t* s1;
|
||||
static int32_t turn_on_fc = QB_FALSE;
|
||||
static int32_t fc_enabled = 89;
|
||||
static int32_t send_event_on_created = QB_FALSE;
|
||||
static int32_t disconnect_after_created = QB_FALSE;
|
||||
static int32_t num_bulk_events = 10;
|
||||
|
||||
static int32_t
|
||||
exit_handler(int32_t rsignal, void *data)
|
||||
@ -108,12 +111,40 @@ s1_msg_process_fn(qb_ipcs_connection_t *c,
|
||||
response.id = IPC_MSG_RES_DISPATCH;
|
||||
response.error = 0;
|
||||
res = qb_ipcs_event_send(c, &response,
|
||||
sizeof(response));
|
||||
sizeof(response));
|
||||
if (res < 0) {
|
||||
qb_perror(LOG_INFO, "qb_ipcs_event_send");
|
||||
}
|
||||
} else if (req_pt->id == IPC_MSG_REQ_BULK_EVENTS) {
|
||||
int32_t m;
|
||||
int32_t num;
|
||||
struct qb_ipcs_connection_stats_2 *stats;
|
||||
|
||||
response.size = sizeof(struct qb_ipc_response_header);
|
||||
response.error = 0;
|
||||
|
||||
stats = qb_ipcs_connection_stats_get_2(c, QB_FALSE);
|
||||
num = stats->event_q_length;
|
||||
free(stats);
|
||||
|
||||
for (m = 0; m < num_bulk_events; m++) {
|
||||
res = qb_ipcs_event_send(c, &response,
|
||||
sizeof(response));
|
||||
ck_assert_int_eq(res, sizeof(response));
|
||||
response.id++;
|
||||
}
|
||||
stats = qb_ipcs_connection_stats_get_2(c, QB_FALSE);
|
||||
ck_assert_int_eq(stats->event_q_length - num, num_bulk_events);
|
||||
free(stats);
|
||||
|
||||
response.id = IPC_MSG_RES_BULK_EVENTS;
|
||||
res = qb_ipcs_response_send(c, &response, response.size);
|
||||
ck_assert_int_eq(res, sizeof(response));
|
||||
|
||||
} else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) {
|
||||
exit(0);
|
||||
} else if (req_pt->id == IPC_MSG_REQ_SERVER_DISCONNECT) {
|
||||
qb_ipcs_disconnect(c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -146,11 +177,36 @@ my_dispatch_del(int32_t fd)
|
||||
return qb_loop_poll_del(my_loop, fd);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
s1_connection_closed(qb_ipcs_connection_t *c)
|
||||
{
|
||||
qb_enter();
|
||||
qb_leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
s1_connection_destroyed(qb_ipcs_connection_t *c)
|
||||
{
|
||||
qb_enter();
|
||||
qb_loop_stop(my_loop);
|
||||
qb_leave();
|
||||
}
|
||||
|
||||
static void
|
||||
s1_connection_created(qb_ipcs_connection_t *c)
|
||||
{
|
||||
if (send_event_on_created) {
|
||||
struct qb_ipc_response_header response;
|
||||
int32_t res;
|
||||
|
||||
response.size = sizeof(struct qb_ipc_response_header);
|
||||
response.id = IPC_MSG_RES_DISPATCH;
|
||||
response.error = 0;
|
||||
res = qb_ipcs_event_send(c, &response,
|
||||
sizeof(response));
|
||||
ck_assert_int_eq(res, response.size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -161,10 +217,10 @@ run_ipc_server(void)
|
||||
|
||||
struct qb_ipcs_service_handlers sh = {
|
||||
.connection_accept = NULL,
|
||||
.connection_created = NULL,
|
||||
.connection_created = s1_connection_created,
|
||||
.msg_process = s1_msg_process_fn,
|
||||
.connection_destroyed = s1_connection_destroyed,
|
||||
.connection_closed = NULL,
|
||||
.connection_closed = s1_connection_closed,
|
||||
};
|
||||
|
||||
struct qb_ipcs_poll_handlers ph = {
|
||||
@ -226,13 +282,14 @@ struct my_req {
|
||||
|
||||
static struct my_req request;
|
||||
static int32_t
|
||||
send_and_check(uint32_t size, int32_t ms_timeout, int32_t expect_perfection)
|
||||
send_and_check(int32_t req_id, uint32_t size,
|
||||
int32_t ms_timeout, int32_t expect_perfection)
|
||||
{
|
||||
struct qb_ipc_response_header res_header;
|
||||
int32_t res;
|
||||
int32_t try_times = 0;
|
||||
|
||||
request.hdr.id = IPC_MSG_REQ_TX_RX;
|
||||
request.hdr.id = req_id;
|
||||
request.hdr.size = sizeof(struct qb_ipc_request_header) + size;
|
||||
|
||||
repeat_send:
|
||||
@ -251,8 +308,16 @@ repeat_send:
|
||||
return res;
|
||||
}
|
||||
}
|
||||
res = qb_ipcc_recv(conn, &res_header,
|
||||
sizeof(struct qb_ipc_response_header), ms_timeout);
|
||||
|
||||
if (req_id == IPC_MSG_REQ_DISPATCH) {
|
||||
res = qb_ipcc_event_recv(conn, &res_header,
|
||||
sizeof(struct qb_ipc_response_header),
|
||||
ms_timeout);
|
||||
} else {
|
||||
res = qb_ipcc_recv(conn, &res_header,
|
||||
sizeof(struct qb_ipc_response_header),
|
||||
ms_timeout);
|
||||
}
|
||||
if (res == -EINTR) {
|
||||
return -1;
|
||||
}
|
||||
@ -263,7 +328,7 @@ repeat_send:
|
||||
}
|
||||
if (expect_perfection) {
|
||||
ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header));
|
||||
ck_assert_int_eq(res_header.id, IPC_MSG_RES_TX_RX);
|
||||
ck_assert_int_eq(res_header.id, req_id + 1);
|
||||
ck_assert_int_eq(res_header.size, sizeof(struct qb_ipc_response_header));
|
||||
}
|
||||
return res;
|
||||
@ -298,7 +363,8 @@ test_ipc_txrx(void)
|
||||
size *= 2;
|
||||
if (size >= MAX_MSG_SIZE)
|
||||
break;
|
||||
if (send_and_check(size, recv_timeout, QB_TRUE) < 0) {
|
||||
if (send_and_check(IPC_MSG_REQ_TX_RX, size,
|
||||
recv_timeout, QB_TRUE) < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -312,9 +378,12 @@ test_ipc_txrx(void)
|
||||
static void
|
||||
test_ipc_exit(void)
|
||||
{
|
||||
struct qb_ipc_request_header req_header;
|
||||
struct qb_ipc_response_header res_header;
|
||||
struct iovec iov[1];
|
||||
int32_t res;
|
||||
int32_t c = 0;
|
||||
int32_t j = 0;
|
||||
int32_t rc = 0;
|
||||
pid_t pid;
|
||||
|
||||
pid = run_function_in_new_process(run_ipc_server);
|
||||
@ -332,9 +401,16 @@ test_ipc_exit(void)
|
||||
} while (conn == NULL && c < 5);
|
||||
fail_if(conn == NULL);
|
||||
|
||||
/* confirm we can send one message */
|
||||
rc = send_and_check(100, recv_timeout, QB_TRUE);
|
||||
_ck_assert_int(rc, >=, 0);
|
||||
req_header.id = IPC_MSG_REQ_TX_RX;
|
||||
req_header.size = sizeof(struct qb_ipc_request_header);
|
||||
|
||||
iov[0].iov_len = req_header.size;
|
||||
iov[0].iov_base = &req_header;
|
||||
|
||||
res = qb_ipcc_sendv_recv(conn, iov, 1,
|
||||
&res_header,
|
||||
sizeof(struct qb_ipc_response_header), -1);
|
||||
ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header));
|
||||
|
||||
/* kill the server */
|
||||
stop_process(pid);
|
||||
@ -350,91 +426,97 @@ test_ipc_exit(void)
|
||||
qb_ipcc_disconnect(conn);
|
||||
}
|
||||
|
||||
START_TEST(test_ipc_exit_us)
|
||||
{
|
||||
qb_enter();
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = 5000;
|
||||
test_ipc_exit();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_exit_shm)
|
||||
{
|
||||
qb_enter();
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = 1000;
|
||||
test_ipc_exit();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_shm_tmo)
|
||||
{
|
||||
qb_enter();
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = 1000;
|
||||
test_ipc_txrx();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_shm_block)
|
||||
{
|
||||
qb_enter();
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = -1;
|
||||
test_ipc_txrx();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_us_block)
|
||||
{
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = -1;
|
||||
test_ipc_txrx();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_us_tmo)
|
||||
{
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = 1000;
|
||||
test_ipc_txrx();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_fc_shm)
|
||||
{
|
||||
qb_enter();
|
||||
turn_on_fc = QB_TRUE;
|
||||
ipc_type = QB_IPC_SHM;
|
||||
recv_timeout = 500;
|
||||
ipc_name = __func__;
|
||||
test_ipc_txrx();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_us_block)
|
||||
{
|
||||
qb_enter();
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = -1;
|
||||
test_ipc_txrx();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_us_tmo)
|
||||
{
|
||||
qb_enter();
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
recv_timeout = 1000;
|
||||
test_ipc_txrx();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_fc_us)
|
||||
{
|
||||
qb_enter();
|
||||
turn_on_fc = QB_TRUE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
recv_timeout = 500;
|
||||
ipc_name = __func__;
|
||||
test_ipc_txrx();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_pmq)
|
||||
{
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_POSIX_MQ;
|
||||
ipc_name = __func__;
|
||||
test_ipc_txrx();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_txrx_smq)
|
||||
{
|
||||
turn_on_fc = QB_FALSE;
|
||||
ipc_type = QB_IPC_SYSV_MQ;
|
||||
ipc_name = __func__;
|
||||
test_ipc_txrx();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -443,15 +525,13 @@ struct my_res {
|
||||
char message[1024 * 1024];
|
||||
};
|
||||
|
||||
static struct my_res response;
|
||||
static void
|
||||
test_ipc_dispatch(void)
|
||||
{
|
||||
int32_t res;
|
||||
int32_t j;
|
||||
int32_t c = 0;
|
||||
pid_t pid;
|
||||
struct qb_ipc_request_header req_header;
|
||||
int32_t size;
|
||||
|
||||
pid = run_function_in_new_process(run_ipc_server);
|
||||
fail_if(pid == -1);
|
||||
@ -468,54 +548,230 @@ test_ipc_dispatch(void)
|
||||
} while (conn == NULL && c < 5);
|
||||
fail_if(conn == NULL);
|
||||
|
||||
req_header.id = IPC_MSG_REQ_DISPATCH;
|
||||
req_header.size = sizeof(struct qb_ipc_request_header);
|
||||
|
||||
repeat_send:
|
||||
res = qb_ipcc_send(conn, &req_header, req_header.size);
|
||||
if (res < 0) {
|
||||
if (res == -EAGAIN) {
|
||||
goto repeat_send;
|
||||
} else if (res == -EINVAL || res == -EINTR) {
|
||||
qb_perror(LOG_INFO, "qb_ipcc_send");
|
||||
return;
|
||||
} else {
|
||||
errno = -res;
|
||||
qb_perror(LOG_INFO, "qb_ipcc_send");
|
||||
goto repeat_send;
|
||||
size = QB_MIN(sizeof(struct qb_ipc_request_header), 64);
|
||||
for (j = 1; j < 19; j++) {
|
||||
size *= 2;
|
||||
if (size >= MAX_MSG_SIZE)
|
||||
break;
|
||||
if (send_and_check(IPC_MSG_REQ_DISPATCH, size,
|
||||
recv_timeout, QB_TRUE) < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
repeat_event_recv:
|
||||
res = qb_ipcc_event_recv(conn, &response, sizeof(struct my_res), 0);
|
||||
if (res < 0) {
|
||||
if (res == -EAGAIN || res == -ETIMEDOUT) {
|
||||
goto repeat_event_recv;
|
||||
} else {
|
||||
errno = -res;
|
||||
qb_perror(LOG_INFO, "qb_ipcc_event_recv");
|
||||
goto repeat_send;
|
||||
}
|
||||
}
|
||||
ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header));
|
||||
ck_assert_int_eq(response.hdr.id, IPC_MSG_RES_DISPATCH);
|
||||
|
||||
qb_ipcc_disconnect(conn);
|
||||
stop_process(pid);
|
||||
}
|
||||
|
||||
START_TEST(test_ipc_disp_shm)
|
||||
{
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
test_ipc_dispatch();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_disp_us)
|
||||
{
|
||||
qb_enter();
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
test_ipc_dispatch();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int32_t events_received;
|
||||
|
||||
|
||||
static int32_t
|
||||
count_bulk_events(int32_t fd, int32_t revents, void *data)
|
||||
{
|
||||
qb_loop_t *cl = (qb_loop_t*)data;
|
||||
|
||||
events_received++;
|
||||
|
||||
if (events_received >= num_bulk_events) {
|
||||
qb_loop_stop(cl);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_ipc_bulk_events(void)
|
||||
{
|
||||
struct qb_ipc_request_header req_header;
|
||||
struct qb_ipc_response_header res_header;
|
||||
struct iovec iov[1];
|
||||
int32_t c = 0;
|
||||
int32_t j = 0;
|
||||
pid_t pid;
|
||||
int32_t res;
|
||||
qb_loop_t *cl;
|
||||
int32_t fd;
|
||||
|
||||
pid = run_function_in_new_process(run_ipc_server);
|
||||
fail_if(pid == -1);
|
||||
sleep(1);
|
||||
|
||||
do {
|
||||
conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE);
|
||||
if (conn == NULL) {
|
||||
j = waitpid(pid, NULL, WNOHANG);
|
||||
ck_assert_int_eq(j, 0);
|
||||
sleep(1);
|
||||
c++;
|
||||
}
|
||||
} while (conn == NULL && c < 5);
|
||||
fail_if(conn == NULL);
|
||||
|
||||
events_received = 0;
|
||||
cl = qb_loop_create();
|
||||
res = qb_ipcc_fd_get(conn, &fd),
|
||||
ck_assert_int_eq(res, 0);
|
||||
res = qb_loop_poll_add(cl, QB_LOOP_MED,
|
||||
fd, POLLIN,
|
||||
cl, count_bulk_events);
|
||||
ck_assert_int_eq(res, 0);
|
||||
|
||||
res = send_and_check(IPC_MSG_REQ_BULK_EVENTS,
|
||||
0,
|
||||
recv_timeout, QB_TRUE);
|
||||
ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header));
|
||||
|
||||
qb_loop_run(cl);
|
||||
ck_assert_int_eq(events_received, num_bulk_events);
|
||||
|
||||
req_header.id = IPC_MSG_REQ_SERVER_FAIL;
|
||||
req_header.size = sizeof(struct qb_ipc_request_header);
|
||||
|
||||
iov[0].iov_len = req_header.size;
|
||||
iov[0].iov_base = &req_header;
|
||||
res = qb_ipcc_sendv_recv(conn, iov, 1,
|
||||
&res_header,
|
||||
sizeof(struct qb_ipc_response_header), -1);
|
||||
if (res != -ECONNRESET && res != -ENOTCONN) {
|
||||
qb_log(LOG_ERR, "id:%d size:%d", res_header.id, res_header.size);
|
||||
ck_assert_int_eq(res, -ENOTCONN);
|
||||
}
|
||||
|
||||
qb_ipcc_disconnect(conn);
|
||||
stop_process(pid);
|
||||
}
|
||||
|
||||
START_TEST(test_ipc_bulk_events_us)
|
||||
{
|
||||
qb_enter();
|
||||
send_event_on_created = QB_FALSE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
test_ipc_bulk_events();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
test_ipc_event_on_created(void)
|
||||
{
|
||||
int32_t c = 0;
|
||||
int32_t j = 0;
|
||||
pid_t pid;
|
||||
int32_t res;
|
||||
qb_loop_t *cl;
|
||||
int32_t fd;
|
||||
|
||||
num_bulk_events = 1;
|
||||
|
||||
pid = run_function_in_new_process(run_ipc_server);
|
||||
fail_if(pid == -1);
|
||||
sleep(1);
|
||||
|
||||
do {
|
||||
conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE);
|
||||
if (conn == NULL) {
|
||||
j = waitpid(pid, NULL, WNOHANG);
|
||||
ck_assert_int_eq(j, 0);
|
||||
sleep(1);
|
||||
c++;
|
||||
}
|
||||
} while (conn == NULL && c < 5);
|
||||
fail_if(conn == NULL);
|
||||
|
||||
events_received = 0;
|
||||
cl = qb_loop_create();
|
||||
res = qb_ipcc_fd_get(conn, &fd),
|
||||
ck_assert_int_eq(res, 0);
|
||||
res = qb_loop_poll_add(cl, QB_LOOP_MED,
|
||||
fd, POLLIN,
|
||||
cl, count_bulk_events);
|
||||
ck_assert_int_eq(res, 0);
|
||||
|
||||
qb_loop_run(cl);
|
||||
ck_assert_int_eq(events_received, num_bulk_events);
|
||||
|
||||
qb_ipcc_disconnect(conn);
|
||||
stop_process(pid);
|
||||
}
|
||||
|
||||
START_TEST(test_ipc_event_on_created_us)
|
||||
{
|
||||
qb_enter();
|
||||
send_event_on_created = QB_TRUE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
test_ipc_event_on_created();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
test_ipc_disconnect_after_created(void)
|
||||
{
|
||||
struct qb_ipc_request_header req_header;
|
||||
struct qb_ipc_response_header res_header;
|
||||
struct iovec iov[1];
|
||||
int32_t c = 0;
|
||||
int32_t j = 0;
|
||||
pid_t pid;
|
||||
int32_t res;
|
||||
|
||||
pid = run_function_in_new_process(run_ipc_server);
|
||||
fail_if(pid == -1);
|
||||
sleep(1);
|
||||
|
||||
do {
|
||||
conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE);
|
||||
if (conn == NULL) {
|
||||
j = waitpid(pid, NULL, WNOHANG);
|
||||
ck_assert_int_eq(j, 0);
|
||||
sleep(1);
|
||||
c++;
|
||||
}
|
||||
} while (conn == NULL && c < 5);
|
||||
fail_if(conn == NULL);
|
||||
|
||||
ck_assert_int_eq(QB_TRUE, qb_ipcc_is_connected(conn));
|
||||
|
||||
req_header.id = IPC_MSG_REQ_SERVER_DISCONNECT;
|
||||
req_header.size = sizeof(struct qb_ipc_request_header);
|
||||
|
||||
iov[0].iov_len = req_header.size;
|
||||
iov[0].iov_base = &req_header;
|
||||
|
||||
res = qb_ipcc_sendv_recv(conn, iov, 1,
|
||||
&res_header,
|
||||
sizeof(struct qb_ipc_response_header), -1);
|
||||
/*
|
||||
* confirm we get -ENOTCONN
|
||||
*/
|
||||
ck_assert_int_eq(res, -ENOTCONN);
|
||||
ck_assert_int_eq(QB_FALSE, qb_ipcc_is_connected(conn));
|
||||
|
||||
qb_ipcc_disconnect(conn);
|
||||
stop_process(pid);
|
||||
}
|
||||
|
||||
START_TEST(test_ipc_disconnect_after_created_us)
|
||||
{
|
||||
qb_enter();
|
||||
disconnect_after_created = QB_TRUE;
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
test_ipc_disconnect_after_created();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -554,6 +810,8 @@ test_ipc_server_fail(void)
|
||||
iov[0].iov_len = req_header.size;
|
||||
iov[0].iov_base = &req_header;
|
||||
|
||||
ck_assert_int_eq(QB_TRUE, qb_ipcc_is_connected(conn));
|
||||
|
||||
res = qb_ipcc_sendv_recv(conn, iov, 1,
|
||||
&res_header,
|
||||
sizeof(struct qb_ipc_response_header), -1);
|
||||
@ -561,6 +819,7 @@ test_ipc_server_fail(void)
|
||||
* confirm we get -ENOTCONN
|
||||
*/
|
||||
ck_assert_int_eq(res, -ENOTCONN);
|
||||
ck_assert_int_eq(QB_FALSE, qb_ipcc_is_connected(conn));
|
||||
|
||||
qb_ipcc_disconnect(conn);
|
||||
stop_process(pid);
|
||||
@ -568,37 +827,67 @@ test_ipc_server_fail(void)
|
||||
|
||||
START_TEST(test_ipc_server_fail_soc)
|
||||
{
|
||||
qb_enter();
|
||||
ipc_type = QB_IPC_SOCKET;
|
||||
ipc_name = __func__;
|
||||
test_ipc_server_fail();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_disp_shm)
|
||||
{
|
||||
qb_enter();
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
test_ipc_dispatch();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_bulk_events_shm)
|
||||
{
|
||||
qb_enter();
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
test_ipc_bulk_events();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_event_on_created_shm)
|
||||
{
|
||||
qb_enter();
|
||||
send_event_on_created = QB_TRUE;
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
test_ipc_event_on_created();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ipc_server_fail_shm)
|
||||
{
|
||||
qb_enter();
|
||||
ipc_type = QB_IPC_SHM;
|
||||
ipc_name = __func__;
|
||||
test_ipc_server_fail();
|
||||
qb_leave();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
static Suite *
|
||||
ipc_suite(void)
|
||||
make_shm_suite(void)
|
||||
{
|
||||
TCase *tc;
|
||||
uid_t uid;
|
||||
Suite *s = suite_create("ipc");
|
||||
Suite *s = suite_create("shm");
|
||||
|
||||
tc = tcase_create("ipc_server_fail_shm");
|
||||
tcase_add_test(tc, test_ipc_server_fail_shm);
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_server_fail_soc");
|
||||
tcase_add_test(tc, test_ipc_server_fail_soc);
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_txrx_shm_block");
|
||||
tcase_add_test(tc, test_ipc_txrx_shm_block);
|
||||
tcase_set_timeout(tc, 6);
|
||||
@ -609,6 +898,44 @@ ipc_suite(void)
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_fc_shm");
|
||||
tcase_add_test(tc, test_ipc_fc_shm);
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_dispatch_shm");
|
||||
tcase_add_test(tc, test_ipc_disp_shm);
|
||||
tcase_set_timeout(tc, 16);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_bulk_events_shm");
|
||||
tcase_add_test(tc, test_ipc_bulk_events_shm);
|
||||
tcase_set_timeout(tc, 16);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_exit_shm");
|
||||
tcase_add_test(tc, test_ipc_exit_shm);
|
||||
tcase_set_timeout(tc, 3);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_event_on_created_shm");
|
||||
tcase_add_test(tc, test_ipc_event_on_created_shm);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static Suite *
|
||||
make_soc_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("socket");
|
||||
TCase *tc;
|
||||
|
||||
tc = tcase_create("ipc_server_fail_soc");
|
||||
tcase_add_test(tc, test_ipc_server_fail_soc);
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_txrx_us_block");
|
||||
tcase_add_test(tc, test_ipc_txrx_us_block);
|
||||
tcase_set_timeout(tc, 6);
|
||||
@ -619,31 +946,14 @@ ipc_suite(void)
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_fc_shm");
|
||||
tcase_add_test(tc, test_ipc_fc_shm);
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_fc_us");
|
||||
tcase_add_test(tc, test_ipc_fc_us);
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
uid = geteuid();
|
||||
if (uid == 0) {
|
||||
tc = tcase_create("ipc_txrx_posix_mq");
|
||||
tcase_add_test(tc, test_ipc_txrx_pmq);
|
||||
tcase_set_timeout(tc, 10);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_txrx_sysv_mq");
|
||||
tcase_add_test(tc, test_ipc_txrx_smq);
|
||||
tcase_set_timeout(tc, 10);
|
||||
suite_add_tcase(s, tc);
|
||||
}
|
||||
tc = tcase_create("ipc_dispatch_shm");
|
||||
tcase_add_test(tc, test_ipc_disp_shm);
|
||||
tcase_set_timeout(tc, 16);
|
||||
tc = tcase_create("ipc_exit_us");
|
||||
tcase_add_test(tc, test_ipc_exit_us);
|
||||
tcase_set_timeout(tc, 6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_dispatch_us");
|
||||
@ -651,9 +961,17 @@ ipc_suite(void)
|
||||
tcase_set_timeout(tc, 16);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_exit_shm");
|
||||
tcase_add_test(tc, test_ipc_exit_shm);
|
||||
tcase_set_timeout(tc, 3);
|
||||
tc = tcase_create("ipc_bulk_events_us");
|
||||
tcase_add_test(tc, test_ipc_bulk_events_us);
|
||||
tcase_set_timeout(tc, 16);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_event_on_created_us");
|
||||
tcase_add_test(tc, test_ipc_event_on_created_us);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ipc_disconnect_after_created_us");
|
||||
tcase_add_test(tc, test_ipc_disconnect_after_created_us);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
@ -663,15 +981,27 @@ int32_t
|
||||
main(void)
|
||||
{
|
||||
int32_t number_failed;
|
||||
SRunner *sr;
|
||||
Suite *s;
|
||||
int32_t do_shm_tests = QB_TRUE;
|
||||
|
||||
Suite *s = ipc_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
#ifdef DISABLE_IPC_SHM
|
||||
do_shm_tests = QB_FALSE;
|
||||
#endif /* DISABLE_IPC_SHM */
|
||||
|
||||
s = make_soc_suite();
|
||||
sr = srunner_create(s);
|
||||
|
||||
if (do_shm_tests) {
|
||||
srunner_add_suite(sr, make_shm_suite());
|
||||
}
|
||||
|
||||
qb_log_init("check", LOG_USER, LOG_EMERG);
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_INFO);
|
||||
QB_LOG_FILTER_FILE, "*", LOG_TRACE);
|
||||
qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
qb_log_format_set(QB_LOG_STDERR, "lib/%f|%l| %b");
|
||||
|
||||
srunner_run_all(sr, CK_VERBOSE);
|
||||
number_failed = srunner_ntests_failed(sr);
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qblog.h>
|
||||
|
||||
extern size_t qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap);
|
||||
extern size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap);
|
||||
extern size_t qb_vsnprintf_deserialize(char *string, size_t strlen, const char *buf);
|
||||
|
||||
|
||||
@ -40,18 +40,35 @@ format_this(char *out, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qb_vsprintf_serialize(buf, fmt, ap);
|
||||
qb_vsnprintf_serialize(buf, QB_LOG_MAX_LEN, fmt, ap);
|
||||
qb_vsnprintf_deserialize(out, QB_LOG_MAX_LEN, buf);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
format_this_up_to(char *out, size_t max_len, const char *fmt, ...)
|
||||
{
|
||||
char buf[QB_LOG_MAX_LEN];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qb_vsnprintf_serialize(buf, max_len, fmt, ap);
|
||||
qb_vsnprintf_deserialize(out, QB_LOG_MAX_LEN, buf);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
START_TEST(test_va_serialize)
|
||||
{
|
||||
char buf[QB_LOG_MAX_LEN];
|
||||
char cmp_buf[QB_LOG_MAX_LEN];
|
||||
|
||||
format_this(buf, "one line");
|
||||
ck_assert_str_eq(buf, "one line");
|
||||
|
||||
format_this(buf, "p1:%p, p2:%p", format_this, buf);
|
||||
snprintf(cmp_buf, QB_LOG_MAX_LEN, "p1:%p, p2:%p", format_this, buf);
|
||||
ck_assert_str_eq(buf, cmp_buf);
|
||||
|
||||
format_this(buf, "s1:%s, s2:%s", "Yes", "Never");
|
||||
ck_assert_str_eq(buf, "s1:Yes, s2:Never");
|
||||
|
||||
@ -83,6 +100,9 @@ START_TEST(test_va_serialize)
|
||||
|
||||
format_this(buf, ":%*d:", 8, 96);
|
||||
ck_assert_str_eq(buf, ": 96:");
|
||||
|
||||
format_this_up_to(buf, 11, "123456789____");
|
||||
ck_assert_str_eq(buf, "123456789_");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -553,16 +573,80 @@ END_TEST
|
||||
|
||||
START_TEST(test_log_long_msg)
|
||||
{
|
||||
qb_log_init("test", LOG_USER, LOG_DEBUG);
|
||||
qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
|
||||
qb_log_format_set(QB_LOG_SYSLOG, "%b");
|
||||
int lpc;
|
||||
int rc;
|
||||
int i, max = 1000;
|
||||
char *buffer = calloc(1, max);
|
||||
|
||||
qb_log(LOG_ERR, "QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07 QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07 QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07");
|
||||
qb_log_init("test", LOG_USER, LOG_DEBUG);
|
||||
rc = qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 1024);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_TRACE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
|
||||
for (lpc = 500; lpc < max; lpc++) {
|
||||
lpc++;
|
||||
for(i = 0; i < max; i++) {
|
||||
buffer[i] = 'a' + (i % 10);
|
||||
}
|
||||
buffer[lpc%600] = 0;
|
||||
qb_log(LOG_INFO, "Message %d %d - %s", lpc, lpc%600, buffer);
|
||||
}
|
||||
|
||||
qb_log_blackbox_write_to_file("blackbox.dump");
|
||||
qb_log_blackbox_print_from_file("blackbox.dump");
|
||||
unlink("blackbox.dump");
|
||||
qb_log_fini();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *log_suite(void)
|
||||
START_TEST(test_threaded_logging)
|
||||
{
|
||||
int32_t t;
|
||||
int32_t rc;
|
||||
|
||||
qb_log_init("test", LOG_USER, LOG_EMERG);
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
|
||||
t = qb_log_custom_open(_test_logger, NULL, NULL, NULL);
|
||||
rc = qb_log_filter_ctl(t, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_INFO);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
qb_log_format_set(t, "%b");
|
||||
rc = qb_log_ctl(t, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = qb_log_ctl(t, QB_LOG_CONF_THREADED, QB_TRUE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
qb_log_thread_start();
|
||||
|
||||
memset(test_buf, 0, sizeof(test_buf));
|
||||
test_priority = 0;
|
||||
num_msgs = 0;
|
||||
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__);
|
||||
|
||||
qb_log_fini();
|
||||
|
||||
ck_assert_int_eq(num_msgs, 10);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *
|
||||
log_suite(void)
|
||||
{
|
||||
TCase *tc;
|
||||
Suite *s = suite_create("logging");
|
||||
@ -600,6 +684,10 @@ static Suite *log_suite(void)
|
||||
tcase_add_test(tc, test_log_filter_fn);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("threaded_logging");
|
||||
tcase_add_test(tc, test_threaded_logging);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@ -105,10 +105,6 @@ START_TEST(test_ring_buffer2)
|
||||
}
|
||||
for (i = 0; i < 100; i++) {
|
||||
l = qb_rb_chunk_peek(t, (void **)&new_data, 0);
|
||||
if (l < 0) {
|
||||
/* no more to read */
|
||||
break;
|
||||
}
|
||||
ck_assert_int_eq(l, sizeof(v));
|
||||
fail_unless(v == *new_data);
|
||||
qb_rb_chunk_reclaim(t);
|
||||
|
||||
@ -28,9 +28,10 @@
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qblog.h>
|
||||
|
||||
#define BUFFER_CHUNK_SIZE (50*50*10)
|
||||
#define ONE_MEG 1048576
|
||||
static qb_ringbuffer_t *rb = NULL;
|
||||
static int keep_reading = QB_TRUE;
|
||||
int8_t buffer[ONE_MEG];
|
||||
|
||||
|
||||
static void sigterm_handler(int32_t num)
|
||||
@ -42,18 +43,18 @@ static void sigterm_handler(int32_t num)
|
||||
int32_t main(int32_t argc, char *argv[])
|
||||
{
|
||||
ssize_t num_read;
|
||||
int8_t buffer[BUFFER_CHUNK_SIZE];
|
||||
|
||||
signal(SIGINT, sigterm_handler);
|
||||
|
||||
qb_log_init("rbreader", LOG_USER, LOG_EMERG);
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_INFO);
|
||||
QB_LOG_FILTER_FILE, "*", LOG_TRACE);
|
||||
qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
|
||||
rb = qb_rb_open("tester", BUFFER_CHUNK_SIZE * 3,
|
||||
QB_RB_FLAG_SHARED_PROCESS | QB_RB_FLAG_CREATE, 0);
|
||||
rb = qb_rb_open("tester", ONE_MEG * 3,
|
||||
QB_RB_FLAG_SHARED_PROCESS |
|
||||
QB_RB_FLAG_CREATE, 0);
|
||||
|
||||
if (rb == NULL) {
|
||||
qb_perror(LOG_ERR, "failed to create ringbuffer");
|
||||
@ -61,8 +62,11 @@ int32_t main(int32_t argc, char *argv[])
|
||||
}
|
||||
while (keep_reading) {
|
||||
num_read = qb_rb_chunk_read(rb, buffer,
|
||||
BUFFER_CHUNK_SIZE, 5500);
|
||||
if (num_read < 0) {
|
||||
ONE_MEG, 0);
|
||||
if (num_read == -ETIMEDOUT) {
|
||||
usleep(100000);
|
||||
} else if (num_read < 0) {
|
||||
errno = -num_read;
|
||||
qb_perror(LOG_ERR, "nothing to read");
|
||||
}
|
||||
}
|
||||
|
||||
120
tests/rbwriter.c
120
tests/rbwriter.c
@ -35,21 +35,16 @@
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qblog.h>
|
||||
|
||||
static int alarm_notice = 0;
|
||||
static qb_ringbuffer_t *rb = NULL;
|
||||
#define ITERATIONS 100000
|
||||
#define BUFFER_CHUNK_SIZE (50*50*10)
|
||||
static qb_util_stopwatch_t *sw;
|
||||
#define ONE_MEG 1048576
|
||||
static char buffer[ONE_MEG * 3];
|
||||
|
||||
static struct timeval tv1, tv2, tv_elapsed;
|
||||
|
||||
#define timersub(a, b, result) \
|
||||
do { \
|
||||
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
||||
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
|
||||
if ((result)->tv_usec < 0) { \
|
||||
--(result)->tv_sec; \
|
||||
(result)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
static void sigalrm_handler (int num)
|
||||
{
|
||||
alarm_notice = 1;
|
||||
}
|
||||
|
||||
static void sigterm_handler(int32_t num)
|
||||
{
|
||||
@ -58,53 +53,56 @@ static void sigterm_handler(int32_t num)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void bm_start(void)
|
||||
static void
|
||||
_benchmark(ssize_t write_size)
|
||||
{
|
||||
gettimeofday(&tv1, NULL);
|
||||
}
|
||||
ssize_t res;
|
||||
int write_count = 0;
|
||||
float secs;
|
||||
|
||||
static void bm_finish(const char *operation, int32_t size)
|
||||
{
|
||||
float ops_per_sec;
|
||||
float mbs_per_sec;
|
||||
alarm_notice = 0;
|
||||
|
||||
gettimeofday(&tv2, NULL);
|
||||
timersub(&tv2, &tv1, &tv_elapsed);
|
||||
alarm (10);
|
||||
|
||||
ops_per_sec =
|
||||
((float)ITERATIONS) / (((float)tv_elapsed.tv_sec) +
|
||||
(((float)tv_elapsed.tv_usec) / 1000000.0));
|
||||
|
||||
mbs_per_sec =
|
||||
((((float)ITERATIONS) * size) /
|
||||
(((float)tv_elapsed.tv_sec) +
|
||||
(((float)tv_elapsed.tv_usec) / 1000000.0))) / (1024.0 * 1024.0);
|
||||
|
||||
qb_log(LOG_INFO, "write size %d OPs/sec %9.3f MB/sec %9.3f",
|
||||
size, ops_per_sec, mbs_per_sec);
|
||||
}
|
||||
|
||||
static void bmc_connect(void)
|
||||
{
|
||||
rb = qb_rb_open("tester", BUFFER_CHUNK_SIZE * 3,
|
||||
QB_RB_FLAG_SHARED_PROCESS, 0);
|
||||
|
||||
if (rb == NULL) {
|
||||
qb_perror(LOG_ERR, "failed to create ringbuffer");
|
||||
exit(1);
|
||||
qb_util_stopwatch_start(sw);
|
||||
do {
|
||||
res = qb_rb_chunk_write(rb, buffer, write_size);
|
||||
if (res == write_size) {
|
||||
write_count++;
|
||||
}
|
||||
} while (alarm_notice == 0 && (res == write_size || res == -EAGAIN));
|
||||
if (res < 0) {
|
||||
perror("qb_ipcc_sendv");
|
||||
}
|
||||
qb_util_stopwatch_stop(sw);
|
||||
secs = qb_util_stopwatch_sec_elapsed_get(sw);
|
||||
|
||||
printf ("%5d messages sent ", write_count);
|
||||
printf ("%5ld bytes per write ", (long int) write_size);
|
||||
printf ("%7.3f Seconds runtime ", secs);
|
||||
printf ("%9.3f TP/s ",
|
||||
((float)write_count) / secs);
|
||||
printf ("%7.3f MB/s.\n",
|
||||
((float)write_count) * ((float)write_size) / secs);
|
||||
}
|
||||
|
||||
static char buffer[1024 * 1024];
|
||||
static void bmc_send_nozc(size_t size)
|
||||
{
|
||||
ssize_t res = 0;
|
||||
|
||||
repeat_send:
|
||||
res = qb_rb_chunk_write(rb, buffer, size);
|
||||
if (res < size) {
|
||||
goto repeat_send;
|
||||
static void
|
||||
do_throughput_benchmark(void)
|
||||
{
|
||||
ssize_t size = 64;
|
||||
int i;
|
||||
|
||||
signal (SIGALRM, sigalrm_handler);
|
||||
sw = qb_util_stopwatch_create();
|
||||
|
||||
for (i = 0; i < 10; i++) { /* number of repetitions - up to 50k */
|
||||
_benchmark(size);
|
||||
signal (SIGALRM, sigalrm_handler);
|
||||
size *= 5;
|
||||
if (size >= ONE_MEG) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +123,6 @@ int32_t main(int32_t argc, char *argv[])
|
||||
{
|
||||
const char *options = "vh";
|
||||
int32_t opt;
|
||||
int32_t i, j;
|
||||
int32_t size;
|
||||
int32_t verbose = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, options)) != -1) {
|
||||
@ -150,21 +146,9 @@ int32_t main(int32_t argc, char *argv[])
|
||||
QB_LOG_FILTER_FILE, "*", LOG_INFO + verbose);
|
||||
qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
|
||||
bmc_connect();
|
||||
|
||||
for (j = 1; j < 49; j++) {
|
||||
bm_start();
|
||||
size = 7 * (j + 1) * j;
|
||||
|
||||
if (size > BUFFER_CHUNK_SIZE) {
|
||||
size = BUFFER_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ITERATIONS; i++) {
|
||||
bmc_send_nozc(size);
|
||||
}
|
||||
bm_finish("ringbuffer", size);
|
||||
}
|
||||
rb = qb_rb_open("tester", ONE_MEG * 3,
|
||||
QB_RB_FLAG_SHARED_PROCESS, 0);
|
||||
do_throughput_benchmark();
|
||||
qb_rb_close(rb);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
RETURN=0
|
||||
ls /dev/shm/qb-test* 2>/dev/null
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo
|
||||
echo "Error: shared memory segments not closed/unlinked"
|
||||
echo
|
||||
RETURN=1
|
||||
fi
|
||||
|
||||
for d in /dev/shm /var/run
|
||||
do
|
||||
ls $d/qb-test* 2>/dev/null
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo
|
||||
echo "Error: shared memory segments not closed/unlinked"
|
||||
echo
|
||||
RETURN=1
|
||||
fi
|
||||
done
|
||||
ps aux | grep -v grep | grep lt-check
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
@ -16,4 +20,3 @@ then
|
||||
fi
|
||||
|
||||
exit $RETURN
|
||||
|
||||
|
||||
28
tools/Makefile.am
Normal file
28
tools/Makefile.am
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2011 Red Hat, Inc.
|
||||
#
|
||||
# Authors: Angus Salkeld <asalkeld@redhat.com>
|
||||
#
|
||||
# This file is part of libqb.
|
||||
#
|
||||
# libqb is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# libqb is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
EXTRA_DIST =
|
||||
CLEANFILES =
|
||||
|
||||
sbin_PROGRAMS = qb-blackbox
|
||||
|
||||
qb_blackbox_SOURCES = qb_blackbox.c $(top_builddir)/include/qb/qblog.h
|
||||
qb_blackbox_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
qb_blackbox_LDADD = $(top_builddir)/lib/libqb.la
|
||||
590
tools/Makefile.in
Normal file
590
tools/Makefile.in
Normal file
@ -0,0 +1,590 @@
|
||||
# Makefile.in generated by automake 1.11.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
sbin_PROGRAMS = qb-blackbox$(EXEEXT)
|
||||
subdir = tools
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/include/config.h \
|
||||
$(top_builddir)/include/qb/qbconfig.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(sbindir)"
|
||||
PROGRAMS = $(sbin_PROGRAMS)
|
||||
am_qb_blackbox_OBJECTS = qb_blackbox-qb_blackbox.$(OBJEXT)
|
||||
qb_blackbox_OBJECTS = $(am_qb_blackbox_OBJECTS)
|
||||
qb_blackbox_DEPENDENCIES = $(top_builddir)/lib/libqb.la
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb
|
||||
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CFLAGS) $(CFLAGS)
|
||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
SOURCES = $(qb_blackbox_SOURCES)
|
||||
DIST_SOURCES = $(qb_blackbox_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CHECK_CFLAGS = @CHECK_CFLAGS@
|
||||
CHECK_LIBS = @CHECK_LIBS@
|
||||
CP = @CP@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GLIB_CFLAGS = @GLIB_CFLAGS@
|
||||
GLIB_LIBS = @GLIB_LIBS@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LINT_FLAGS = @LINT_FLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PKGCONFIG = @PKGCONFIG@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SOCKETDIR = @SOCKETDIR@
|
||||
SPLINT = @SPLINT@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
# Copyright (c) 2011 Red Hat, Inc.
|
||||
#
|
||||
# Authors: Angus Salkeld <asalkeld@redhat.com>
|
||||
#
|
||||
# This file is part of libqb.
|
||||
#
|
||||
# libqb is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# libqb is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
EXTRA_DIST =
|
||||
CLEANFILES =
|
||||
qb_blackbox_SOURCES = qb_blackbox.c $(top_builddir)/include/qb/qblog.h
|
||||
qb_blackbox_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
qb_blackbox_LDADD = $(top_builddir)/lib/libqb.la
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu tools/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
install-sbinPROGRAMS: $(sbin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
then echo "$$p"; echo "$$p"; else :; fi; \
|
||||
done | \
|
||||
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
|
||||
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
|
||||
sed 'N;N;N;s,\n, ,g' | \
|
||||
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
|
||||
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
|
||||
if ($$2 == $$4) files[d] = files[d] " " $$1; \
|
||||
else { print "f", $$3 "/" $$4, $$1; } } \
|
||||
END { for (d in files) print "f", d, files[d] }' | \
|
||||
while read type dir files; do \
|
||||
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
|
||||
} \
|
||||
; done
|
||||
|
||||
uninstall-sbinPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
files=`for p in $$list; do echo "$$p"; done | \
|
||||
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
|
||||
-e 's/$$/$(EXEEXT)/' `; \
|
||||
test -n "$$list" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(sbindir)" && rm -f $$files
|
||||
|
||||
clean-sbinPROGRAMS:
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list || exit $$?; \
|
||||
test -n "$(EXEEXT)" || exit 0; \
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
qb-blackbox$(EXEEXT): $(qb_blackbox_OBJECTS) $(qb_blackbox_DEPENDENCIES) $(EXTRA_qb_blackbox_DEPENDENCIES)
|
||||
@rm -f qb-blackbox$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(qb_blackbox_OBJECTS) $(qb_blackbox_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qb_blackbox-qb_blackbox.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
qb_blackbox-qb_blackbox.o: qb_blackbox.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qb_blackbox-qb_blackbox.o -MD -MP -MF $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo -c -o qb_blackbox-qb_blackbox.o `test -f 'qb_blackbox.c' || echo '$(srcdir)/'`qb_blackbox.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo $(DEPDIR)/qb_blackbox-qb_blackbox.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qb_blackbox.c' object='qb_blackbox-qb_blackbox.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qb_blackbox-qb_blackbox.o `test -f 'qb_blackbox.c' || echo '$(srcdir)/'`qb_blackbox.c
|
||||
|
||||
qb_blackbox-qb_blackbox.obj: qb_blackbox.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qb_blackbox-qb_blackbox.obj -MD -MP -MF $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo -c -o qb_blackbox-qb_blackbox.obj `if test -f 'qb_blackbox.c'; then $(CYGPATH_W) 'qb_blackbox.c'; else $(CYGPATH_W) '$(srcdir)/qb_blackbox.c'; fi`
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo $(DEPDIR)/qb_blackbox-qb_blackbox.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qb_blackbox.c' object='qb_blackbox-qb_blackbox.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qb_blackbox-qb_blackbox.obj `if test -f 'qb_blackbox.c'; then $(CYGPATH_W) 'qb_blackbox.c'; else $(CYGPATH_W) '$(srcdir)/qb_blackbox.c'; fi`
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(sbindir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-sbinPROGRAMS
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-sbinPROGRAMS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-sbinPROGRAMS ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-sbinPROGRAMS install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-sbinPROGRAMS
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
34
tools/qb_blackbox.c
Normal file
34
tools/qb_blackbox.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Andrew Beekhof <andrew@beekhof.net>
|
||||
*
|
||||
* libqb is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <qb/qblog.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int lpc = 0;
|
||||
|
||||
qb_log_init("qb_blackbox", LOG_USER, LOG_TRACE);
|
||||
qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, "*", LOG_TRACE);
|
||||
|
||||
for(lpc = 1; lpc < argc && argv[lpc] != NULL; lpc++) {
|
||||
printf("Dumping the contents of %s\n", argv[lpc]);
|
||||
qb_log_blackbox_print_from_file(argv[lpc]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user