Skip to content

Commit fc0ef94

Browse files
committed
add send function to targets
1 parent af39475 commit fc0ef94

File tree

11 files changed

+259
-152
lines changed

11 files changed

+259
-152
lines changed

include/private/target.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,28 @@
2727
void
2828
destroy_target( const struct stumpless_target *target );
2929

30+
/**
31+
* Initializes a given target structure.
32+
*
33+
* **Thread Safety: MT-Unsafe**
34+
* This function is not thread safe, as it initializes the lock that is
35+
* otherwise used to coordinate changes
36+
*
37+
* **Async Signal Safety: AS-Unsafe**
38+
* This function is not safe to call from signal handlers due to the
39+
* initialization of the lock.
40+
*
41+
* **Async Cancel Safety: AC-Unsafe**
42+
* This function is not safe to call from signal handlers due to the
43+
* initialization of the lock.
44+
*
45+
* @param target The target structure to initialize.
46+
*
47+
* @return The initialized target, or NULL if an error occurs.
48+
*/
49+
struct stumpless_target *
50+
load_target( struct stumpless_target *target );
51+
3052
void
3153
lock_target( const struct stumpless_target *target );
3254

@@ -89,6 +111,9 @@ target_free_thread( void );
89111
int
90112
unchecked_get_option( const struct stumpless_target *target, int option );
91113

114+
void
115+
unload_target( const struct stumpless_target *target );
116+
92117
void
93118
unlock_target( const struct stumpless_target *target );
94119

include/private/target/buffer.h

Lines changed: 9 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: Apache-2.0 */
22

33
/*
4-
* Copyright 2018-2020 Joel E. Anderson
4+
* Copyright 2018-2025 Joel E. Anderson
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -17,11 +17,11 @@
1717
*/
1818

1919
#ifndef __STUMPLESS_PRIVATE_TARGET_BUFFER_H
20-
# define __STUMPLESS_PRIVATE_TARGET_BUFFER_H
20+
#define __STUMPLESS_PRIVATE_TARGET_BUFFER_H
2121

22-
# include <stddef.h>
23-
# include <stumpless/config.h>
24-
# include "private/config/wrapper/thread_safety.h"
22+
#include <stddef.h>
23+
#include <stumpless/config.h>
24+
#include "private/config/wrapper/thread_safety.h"
2525

2626
/**
2727
* Internal representation of a buffer target.
@@ -30,6 +30,8 @@
3030
* of the buffer is reached, and writing over older messages.
3131
*/
3232
struct buffer_target {
33+
/** The base target structure. */
34+
struct stumpless_target target;
3335
/** The buffer logged messages are written into. */
3436
char *buffer;
3537
/** The size of buffer. */
@@ -43,68 +45,13 @@ struct buffer_target {
4345
* Protects updates to buffer and the position counters. This mutex must be
4446
* locked by a thread before it can read from or write to the buffer.
4547
*
46-
* Size is _not_ protected by this mutex, as it must not change over the life
47-
* of the buffer target.
48+
* The size field is _not_ protected by this mutex, as it must not change over
49+
* the life of the buffer target.
4850
*/
4951
config_mutex_t buffer_mutex;
5052
# endif
5153
};
5254

53-
/**
54-
* @brief Cleans up and deallocates a buffer target structure.
55-
*
56-
* This function is responsible for releasing the resources associated with
57-
* a `buffer_target` structure. Specifically, it destroys the mutex protecting
58-
* the buffer and frees the memory occupied by the `buffer_target` instance.
59-
*
60-
* **Thread Safety: MT-Unsafe**
61-
* The caller must ensure that no other threads are accessing the buffer_target
62-
* while this function is executed.
63-
*
64-
* **Async Signal Safety: AS-Unsafe*
65-
* The function destroys a mutex, which is not safe to use in a signal handler context.
66-
*
67-
* **Async Cancel Safety: AC-Unsafe**
68-
* The function is not safe to call from threads that may be asynchronously canceled.
69-
* If a thread is canceled while destroying the mutex or freeing memory, it might leave
70-
* the program in an inconsistent state.
71-
*
72-
* @param target A pointer to the `buffer_target` structure to be destroyed.
73-
* Must not be `NULL`.
74-
*/
75-
void
76-
destroy_buffer_target( const struct buffer_target *target );
77-
78-
/**
79-
* @brief Creates and initializes a new buffer target structure.
80-
*
81-
* This function allocates memory for a `buffer_target` structure and initializes
82-
* its fields. The buffer target is designed to manage a pre-allocated buffer
83-
* with specified size, enabling read and write operations.
84-
*
85-
* **Thread Safety: MT-Safe**
86-
* The function is thread-safe because it initializes a mutex (buffer_mutex)
87-
* specifically for the buffer_target. This ensures that subsequent operations on
88-
* the buffer_target can be performed in a thread-safe manner.
89-
*
90-
* **Async Signal Safety: AS-Unsafe*
91-
* It uses dynamic memory allocation (e.g., malloc or similar), which is not signal-safe.
92-
*
93-
* **Async Cancel Safety: AC-Unsafe**
94-
* The function is not safe to call from threads that may be asynchronously canceled
95-
* because the memory allocation (or its failure) might not handle thread cancellation properly
96-
*
97-
* @param buffer A pointer to the pre-allocated memory buffer that this target
98-
* will manage. This buffer must be valid for the lifetime of the
99-
* `buffer_target` structure.
100-
* @param size The size of the buffer in bytes.
101-
*
102-
* @return A pointer to the newly allocated and initialized `buffer_target`
103-
* structure, or `NULL` if memory allocation fails.
104-
*/
105-
struct buffer_target *
106-
new_buffer_target( char *buffer, size_t size );
107-
10855
/**
10956
* @brief Writes a message to a buffer target, wrapping around if needed.
11057
*

include/stumpless/target.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,29 @@ typedef struct stumpless_entry * ( *stumpless_map_func_t )(
165165
const struct stumpless_entry *entry,
166166
void *data );
167167

168+
/**
169+
* A function that sends an entry to a target.
170+
*
171+
* The send function is responsible for actually sending the entry to the
172+
* target. It does not handle any per-target tasks such as filtering.
173+
*
174+
* @since release v3.0.0
175+
*
176+
* @param target The target to send the entry to.
177+
*
178+
* @param entry The entry to send to the target.
179+
*
180+
* @data A pointer to data that may hold anything that the logging function
181+
* needs to use in addition to the target and entry.
182+
*
183+
* @return A non-negative number if no error was encountered. Otherwise, a
184+
* negative number must be returned.
185+
*/
186+
typedef int ( *stumpless_send_func_t )(
187+
const struct stumpless_target *target,
188+
const struct stumpless_entry *entry,
189+
void *data );
190+
168191
/**
169192
* A target that log entries can be sent to.
170193
*/
@@ -243,6 +266,19 @@ struct stumpless_target {
243266
* @since release v3.0.0
244267
*/
245268
void *map_data;
269+
/**
270+
* The function to use to log entries after filtering and mapping. This must
271+
* not be NULL.
272+
*
273+
* @since release v3.0.0
274+
*/
275+
stumpless_send_func_t send;
276+
/**
277+
* A pointer to data which may be used by the send function.
278+
*
279+
* @since release v3.0.0
280+
*/
281+
void *send_data;
246282
#ifdef STUMPLESS_THREAD_SAFETY_SUPPORTED
247283
/**
248284
* A pointer to a mutex which protects all target fields. The exact type of

include/stumpless/target/buffer.h

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,36 @@
4141
*/
4242

4343
#ifndef __STUMPLESS_TARGET_BUFFER_H
44-
# define __STUMPLESS_TARGET_BUFFER_H
44+
#define __STUMPLESS_TARGET_BUFFER_H
4545

46-
# include <stddef.h>
47-
# include <stumpless/config.h>
48-
# include <stumpless/target.h>
46+
#include <stddef.h>
47+
#include <stumpless/config.h>
48+
#include <stumpless/target.h>
4949

50-
# ifdef __cplusplus
50+
#ifdef __cplusplus
5151
extern "C" {
52-
# endif
52+
#endif
53+
54+
/**
55+
* Sends an entry to a buffer target.
56+
*
57+
* @since release v3.0.0
58+
*
59+
* @param target The target to send the entry to.
60+
*
61+
* @param entry The entry to send to the target.
62+
*
63+
* @data A pointer to data that may hold anything that the logging function
64+
* needs to use in addition to the target and entry.
65+
*
66+
* @return A non-negative number if no error was encountered. Otherwise, a
67+
* negative number must be returned.
68+
*/
69+
STUMPLESS_PUBLIC_FUNCTION
70+
int
71+
stumpless_buffer_send( const struct stumpless_target *target,
72+
const struct stumpless_entry *entry,
73+
void *data );
5374

5475
/**
5576
* Closes a buffer target.
@@ -161,7 +182,7 @@ stumpless_read_buffer( struct stumpless_target *target,
161182
char *buffer,
162183
size_t max_length );
163184

164-
# ifdef __cplusplus
185+
#ifdef __cplusplus
165186
} /* extern "C" */
166-
# endif
187+
#endif
167188
#endif /* __STUMPLESS_TARGET_BUFFER_H */

src/target.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: Apache-2.0
22

33
/*
4-
* Copyright 2018-2024 Joel E. Anderson
4+
* Copyright 2018-2025 Joel E. Anderson
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@
3131
#include <stumpless/param.h>
3232
#include <stumpless/severity.h>
3333
#include <stumpless/target.h>
34-
#include <stumpless/error.h>
3534
#include <stumpless/target/buffer.h>
3635
#include <stumpless/target/file.h>
3736
#include <stumpless/target/function.h>
@@ -259,7 +258,8 @@ stumpless_add_entry( struct stumpless_target *target,
259258
switch ( target->type ) {
260259

261260
case STUMPLESS_BUFFER_TARGET:
262-
result = sendto_buffer_target( target->id, buffer, builder_length );
261+
//result = sendto_buffer_target( ( struct buffer_target * ) target, buffer, builder_length );
262+
result = target->send( target, entry, target->send_data );
263263
break;
264264

265265
case STUMPLESS_FILE_TARGET:
@@ -1147,13 +1147,35 @@ vstumpless_trace_message( struct stumpless_target *target,
11471147

11481148
void
11491149
destroy_target( const struct stumpless_target *target ) {
1150-
config_compare_exchange_ptr( &current_target, target, NULL );
1151-
1152-
config_destroy_cached_mutex( target->mutex );
1150+
unload_target( target );
11531151
free_mem( target->name );
11541152
free_mem( target );
11551153
}
11561154

1155+
struct stumpless_target *
1156+
load_target( struct stumpless_target *target ){
1157+
config_assign_cached_mutex( target->mutex );
1158+
if( !config_check_mutex_valid( target->mutex ) ) {
1159+
return NULL;
1160+
}
1161+
1162+
target->options = stumpless_get_default_options();
1163+
target->default_prival = get_prival( STUMPLESS_DEFAULT_FACILITY,
1164+
STUMPLESS_DEFAULT_SEVERITY );
1165+
target->default_app_name[0] = '-';
1166+
target->default_app_name_length = 1;
1167+
target->default_msgid[0] = '-';
1168+
target->default_msgid_length = 1;
1169+
target->mask = STUMPLESS_SEVERITY_MASK_UPTO( STUMPLESS_SEVERITY_DEBUG_VALUE );
1170+
target->filter = stumpless_mask_filter;
1171+
target->filter_data = NULL;
1172+
target->map = NULL;
1173+
target->map_data = NULL;
1174+
target->send_data = NULL;
1175+
1176+
return target;
1177+
}
1178+
11571179
void
11581180
lock_target( const struct stumpless_target *target ) {
11591181
config_lock_mutex( target->mutex );
@@ -1177,29 +1199,14 @@ new_target( enum stumpless_target_type type, const char *name ) {
11771199
target->name = NULL;
11781200
}
11791201

1180-
config_assign_cached_mutex( target->mutex );
1181-
if( !config_check_mutex_valid( target->mutex ) ) {
1182-
goto fail_mutex;
1202+
if( !load_target( target ) ){
1203+
goto fail_load;
11831204
}
1184-
1185-
target->id = NULL;
11861205
target->type = type;
1187-
target->options = stumpless_get_default_options();
1188-
target->default_prival = get_prival( STUMPLESS_DEFAULT_FACILITY,
1189-
STUMPLESS_DEFAULT_SEVERITY );
1190-
target->default_app_name[0] = '-';
1191-
target->default_app_name_length = 1;
1192-
target->default_msgid[0] = '-';
1193-
target->default_msgid_length = 1;
1194-
target->mask = STUMPLESS_SEVERITY_MASK_UPTO( STUMPLESS_SEVERITY_DEBUG_VALUE );
1195-
target->filter = stumpless_mask_filter;
1196-
target->filter_data = NULL;
1197-
target->map = NULL;
1198-
target->map_data = NULL;
11991206

12001207
return target;
12011208

1202-
fail_mutex:
1209+
fail_load:
12031210
free_mem( target->name );
12041211
target->name = NULL;
12051212
fail_name:
@@ -1277,6 +1284,12 @@ target_free_thread( void ) {
12771284
}
12781285
}
12791286

1287+
void
1288+
unload_target( const struct stumpless_target *target ){
1289+
config_compare_exchange_ptr( &current_target, target, NULL );
1290+
config_destroy_cached_mutex( target->mutex );
1291+
}
1292+
12801293
void
12811294
unlock_target( const struct stumpless_target *target ) {
12821295
config_unlock_mutex( target->mutex );

0 commit comments

Comments
 (0)