marsrs-react-native-xlog 0.1.0-alpha.3 → 0.1.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,9 +27,13 @@
27
27
  * caller can include it without running cbindgen. It is kept in sync with
28
28
  * `src/abi.rs` by `tests/header_sync.rs`.
29
29
  *
30
- * Threading: every symbol may be called from any thread. `mars_xlog_open`,
31
- * `mars_xlog_close` and the setters mutate process-wide state (exactly like the
32
- * C++ globals) and should be called from one place during start-up / shut-down.
30
+ * Threading: every symbol may be called from any thread. The setters and the
31
+ * instance lifecycle mutate shared state (exactly like the C++ globals) and
32
+ * should be called from one place during start-up / shut-down. What no symbol
33
+ * here does is install a process-wide appender: an app opens an instance with
34
+ * `mars_xlog_new_instance` and writes through the handle it answers. Handle
35
+ * `0` names no appender at all — it is what an open that failed answers, and
36
+ * every symbol asked of it is a no-op.
33
37
  *
34
38
  * Panics: no Rust panic ever crosses this boundary. Every entry point is
35
39
  * wrapped in `catch_unwind`; a panic is reported as `MARS_XLOG_ERR_PANIC` (or
@@ -39,6 +43,17 @@
39
43
  #ifndef MARS_XLOG_H_
40
44
  #define MARS_XLOG_H_
41
45
 
46
+ /* The symbols this header declares are the ones `#[no_mangle]` exports: plain
47
+ * C names, and a C++ translation unit that includes this and calls
48
+ * `mars_xlog_new_instance()` asks its linker for a mangled one that does not
49
+ * exist.
50
+ * `mars_stn.h` and `mars_sdt.h` carry the same guard, and `mars_xlog.hpp` —
51
+ * the C++ face of this seam — includes this one, so a C++ caller asks for the
52
+ * same names whichever of the two it takes. */
53
+ #ifdef __cplusplus
54
+ extern "C" {
55
+ #endif
56
+
42
57
  /* --- enums ------------------------------------------------------------- */
43
58
 
44
59
  /** Mirrors `mars::xlog::TAppenderMode` (appender.h). */
@@ -60,8 +75,14 @@ typedef enum {
60
75
  /** Additional level understood only by the filter: disables every record. */
61
76
  #define MARS_LEVEL_NONE 6
62
77
 
63
- /* --- return codes ------------------------------------------------------- */
64
-
78
+ /* --- return codes -------------------------------------------------------
79
+ *
80
+ * The five from `NULL_CONFIG` to `APPENDER` are the reasons an open may be
81
+ * refused, and no symbol hands them out: `mars_xlog_new_instance` answers the
82
+ * handle `0` for every one of them, there being no room in a handle for a
83
+ * negative code. They are here for the caller that wants to name the reason in
84
+ * its own diagnostic, not to switch on an answer.
85
+ */
65
86
  #define MARS_XLOG_OK 0
66
87
  #define MARS_XLOG_ERR_NULL_CONFIG (-1) /* `config` was NULL */
67
88
  #define MARS_XLOG_ERR_BAD_MODE (-2) /* `mode` outside MarsAppenderMode */
@@ -73,17 +94,6 @@ typedef enum {
73
94
  #define MARS_XLOG_ERR_NO_PATH (-8) /* no current log file is open */
74
95
  #define MARS_XLOG_ERR_PANIC (-99) /* a Rust panic was caught at the boundary */
75
96
 
76
- /* --- `mars_xlog_oneshot_flush` result: mars::xlog::TFileIOAction --------- */
77
-
78
- #define MARS_XLOG_ACTION_NONE 0
79
- #define MARS_XLOG_ACTION_SUCCESS 1
80
- #define MARS_XLOG_ACTION_UNNECESSARY 2 /* there was nothing to flush */
81
- #define MARS_XLOG_ACTION_OPEN_FAILED 3
82
- #define MARS_XLOG_ACTION_READ_FAILED 4
83
- #define MARS_XLOG_ACTION_WRITE_FAILED 5
84
- #define MARS_XLOG_ACTION_CLOSE_FAILED 6
85
- #define MARS_XLOG_ACTION_REMOVE_FAILED 7
86
-
87
97
  /* --- config ------------------------------------------------------------- */
88
98
 
89
99
  /**
@@ -95,7 +105,7 @@ typedef enum {
95
105
  typedef struct {
96
106
  int mode; /* MarsAppenderMode; default when unset: Async */
97
107
  const char* log_dir; /* mandatory, directory is created if missing */
98
- const char* name_prefix; /* used verbatim; no default, as in C++ */
108
+ const char* name_prefix; /* used verbatim; no default; "" is refused */
99
109
  const char* pub_key; /* NULL / "" => logs are written unencrypted */
100
110
  int compress_mode; /* MarsCompressMode; default when unset: Zlib */
101
111
  int compress_level; /* <= 0 => keep the appender default (6) */
@@ -103,79 +113,44 @@ typedef struct {
103
113
  int cache_days; /* < 0 => 0; 0 => keep every file */
104
114
  } MarsXLogConfig;
105
115
 
106
- /* --- lifecycle ---------------------------------------------------------- */
107
-
108
- /**
109
- * Replaces `mars::xlog::appender_open(const XLogConfig&)`.
110
- *
111
- * @return MARS_XLOG_OK (0) on success, or a negative MARS_XLOG_ERR_* code.
112
- */
113
- int mars_xlog_open(const MarsXLogConfig* config);
114
-
115
- /**
116
- * Replaces `mars::xlog::XloggerWrite(...)` / `appender_write`. The record is
117
- * dropped (cheaply, before any formatting) when `level` is below the level set
118
- * by `mars_xlog_set_level`.
119
- *
120
- * `tag`, `filename`, `func_name` and `message` may be NULL; NULL and invalid
121
- * UTF-8 are treated as an empty string.
122
- */
123
- void mars_xlog_write(int level,
124
- const char* tag,
125
- const char* filename,
126
- const char* func_name,
127
- int line,
128
- const char* message);
129
-
130
- /** Replaces `mars::xlog::appender_flush()` — signals the writer thread. */
131
- void mars_xlog_flush(void);
132
-
133
- /** Replaces `mars::xlog::appender_flush_sync()` — flushes and waits. */
134
- void mars_xlog_flush_sync(void);
135
-
136
- /** Replaces `mars::xlog::appender_close()`. */
137
- void mars_xlog_close(void);
138
-
139
- /** Replaces `xlogger_SetLevel()`; `level` < 0 clamps to Verbose. */
140
- void mars_xlog_set_level(int level);
141
-
142
- /** Replaces `appender_set_console_log(bool)`; `open` != 0 means on. */
143
- void mars_xlog_set_console_log(int open);
144
-
145
- /** Replaces `appender_set_max_file_size(uint64_t)`; 0 means "do not split". */
146
- void mars_xlog_set_max_file_size(unsigned long long bytes);
147
-
148
- /** Replaces `appender_set_max_alive_duration(long)`; negative clamps to 0. */
149
- void mars_xlog_set_max_alive_duration(long long seconds);
150
-
151
- /**
152
- * Replaces `appender_get_current_log_path(char*, unsigned int)`.
153
- *
154
- * Writes the NUL-terminated path of the log file currently being appended to
155
- * into `out` (which must hold at least `len` bytes).
156
- *
157
- * @return the number of bytes written excluding the terminating NUL, or a
158
- * negative MARS_XLOG_ERR_* code (`MARS_XLOG_ERR_NULL_OUT`,
159
- * `MARS_XLOG_ERR_NO_SPACE`, `MARS_XLOG_ERR_NO_PATH`).
160
- */
161
- int mars_xlog_current_log_path(char* out, unsigned int len);
162
-
163
116
  /* ---- logger instances (mars::xlog::NewXloggerInstance and friends) ----
164
117
  *
165
118
  * Each instance owns an appender: its own log directory, prefix, key, mode and
166
- * cache file. Handle 0 means "the process-wide appender opened by
167
- * mars_xlog_open".
119
+ * cache file. A C caller that wants a logger opens one with
120
+ * mars_xlog_new_instance and holds the handle it answers.
121
+ *
122
+ * Every call that can be asked of an instance exists only in this spelling:
123
+ * the C++ has a free function for its process-wide appender and a
124
+ * handle-taking one beside it, and a second spelling of the same operation
125
+ * here would be two ways to say one thing. There is no process-wide appender
126
+ * to install, so there is no free-function spelling either — and handle `0`,
127
+ * which is what a failed open answers, names no appender: the level, the mode,
128
+ * the console, the two sizes and the drain asked of it do nothing, and the
129
+ * questions answer "no" or `MARS_XLOG_ERR_NO_PATH`.
168
130
  */
169
131
 
132
+ /* --- writing ------------------------------------------------------------- */
133
+
170
134
  /* Returns the instance handle, or 0 on a null/invalid config. */
171
135
  long long mars_xlog_new_instance(const MarsXLogConfig* config, int level);
172
136
 
173
137
  /* The handle registered for name_prefix, or 0 when there is none. */
174
138
  long long mars_xlog_get_instance(const char* name_prefix);
175
139
 
176
- /* Releases the instance and closes its appender. */
140
+ /* Releases the instance and closes its appender. Prefer the handle-aware
141
+ * mars_xlog_release_instance_of() when the caller holds an instance handle. */
177
142
  void mars_xlog_release_instance(const char* name_prefix);
178
143
 
144
+ /* The same, and only while name_prefix is still registered under `instance`.
145
+ *
146
+ * Releasing takes the prefix and not the handle, so asking
147
+ * mars_xlog_get_instance and then calling mars_xlog_release_instance is two
148
+ * answers and not one: an open of the same prefix that lands between the two is
149
+ * handed a handle of its own, and the release closes that one. This is the
150
+ * question and the release in one call, which is also what makes a second
151
+ * close of a prefix a no-op however many callers hold its handle. */
152
+ void mars_xlog_release_instance_of(const char* name_prefix, long long instance);
153
+
179
154
  /* Writes through an instance; honours the instance's level. */
180
155
  void mars_xlog_write_instance(long long instance,
181
156
  int level,
@@ -191,22 +166,31 @@ int mars_xlog_is_enabled_for(long long instance, int level);
191
166
  /* The instance's level, or -1 for an unknown handle. */
192
167
  int mars_xlog_get_level(long long instance);
193
168
 
194
- /* SetLevel for an instance (0 = the default logger). */
169
+ /* SetLevel for an instance: the level `mars_xlog_get_level` and
170
+ * `mars_xlog_is_enabled_for` answer, and the one a write through the same
171
+ * handle asks. A no-op for handle `0`, which is no instance at all. */
195
172
  void mars_xlog_set_level_instance(long long instance, int level);
196
173
 
197
- /* appender_setmode: switches the process-wide appender between async/sync. */
198
- void mars_xlog_set_mode(int mode);
199
-
200
- /* SetAppenderMode for an instance. */
174
+ /* appender_setmode / SetAppenderMode for an instance. */
201
175
  void mars_xlog_set_mode_instance(long long instance, int mode);
202
176
 
203
- /* Drains an instance; sync != 0 waits for the write to complete. */
204
- void mars_xlog_flush_instance(long long instance, int sync);
205
-
206
- /* FlushAll: drains the process-wide appender *and* every instance. */
207
- void mars_xlog_flush_all(int sync);
208
-
209
- /* SetConsoleLogOpen for an instance (0 = the default logger). */
177
+ /* Drains an instance, requested: the writer thread is told it may drain, and
178
+ * this returns at once. Nothing is in the file because this returned, and
179
+ * nothing answers when the drain is over. The C++'s name for this call is
180
+ * `appender_flush`, and "flush" there said which mode the appender was opened
181
+ * in and not what the call does to the thread it was called on: the port names
182
+ * the drain by what the caller gets back, and what this one gives is no answer
183
+ * at all — hence "request", which is the one thing the two drains that do
184
+ * answer, `mars_xlog_flush_now_instance` and the awaited `flush()` every
185
+ * platform carries, do give. */
186
+ void mars_xlog_request_flush_instance(long long instance);
187
+
188
+ /* Drains an instance on the calling thread, which is what
189
+ * `appender_flush_sync` is: its records are on the disk when this returns, and
190
+ * that is a promise the requested call above does not make. */
191
+ void mars_xlog_flush_now_instance(long long instance);
192
+
193
+ /* SetConsoleLogOpen for an instance. */
210
194
  void mars_xlog_set_console_log_instance(long long instance, int open);
211
195
 
212
196
  /* SetMaxFileSize for an instance; 0 means "do not split". */
@@ -215,51 +199,44 @@ void mars_xlog_set_max_file_size_instance(long long instance, unsigned long long
215
199
  /* SetMaxAliveTime for an instance; negative clamps to 0. */
216
200
  void mars_xlog_set_max_alive_duration_instance(long long instance, long long seconds);
217
201
 
218
- /**
219
- * Replaces `mars::xlog::appender_oneshot_flush()`: drains the
220
- * `<prefix>[_<n>].mmap3` cache files another process left behind, without
221
- * opening an appender. The ones a live writer of this process — or of any
222
- * other — still holds are left alone, so it answers
223
- * MARS_XLOG_ACTION_UNNECESSARY when there is nothing of a dead process's to
224
- * recover.
225
- *
226
- * @return one of the MARS_XLOG_ACTION_* values (0..7), or a negative
227
- * MARS_XLOG_ERR_* code when `config` is unusable.
228
- */
229
- int mars_xlog_oneshot_flush(const MarsXLogConfig* config);
230
-
231
202
  /**
232
203
  * Replaces `mars::xlog::appender_make_logfile_name()`: the log file *name* for
233
204
  * the day `timespan` days ago (0 = today), whether or not it exists yet.
234
205
  *
235
206
  * The C++ fills a `std::vector`; a C caller walks the same list with `index`,
236
- * starting at 0 and stopping at MARS_XLOG_ERR_NO_PATH. `prefix` and `log_dir`
237
- * may be NULL (an empty `log_dir` yields no name at all).
207
+ * starting at 0 and stopping at MARS_XLOG_ERR_NO_PATH. `instance` is a handle
208
+ * from `mars_xlog_new_instance`; a handle no appender is open for answers
209
+ * MARS_XLOG_ERR_NO_PATH from the first index.
238
210
  *
239
211
  * @return the number of bytes written excluding the terminating NUL, or a
240
212
  * negative MARS_XLOG_ERR_* code.
241
213
  */
242
- int mars_xlog_make_logfile_name(int timespan,
243
- const char* prefix,
244
- const char* log_dir,
245
- unsigned int index,
246
- char* out,
247
- unsigned int len);
214
+ int mars_xlog_make_logfile_name_instance(long long instance,
215
+ int timespan,
216
+ unsigned int index,
217
+ char* out,
218
+ unsigned int len);
248
219
 
249
220
  /**
250
221
  * Replaces `mars::xlog::appender_getfilepath_from_timespan()`: the log files
251
222
  * that *exist* for the day `timespan` days ago. Same `index` protocol as
252
- * mars_xlog_make_logfile_name.
223
+ * mars_xlog_make_logfile_name_instance.
253
224
  */
254
- int mars_xlog_getfilepath_from_timespan(int timespan,
255
- const char* prefix,
256
- const char* log_dir,
257
- unsigned int index,
258
- char* out,
259
- unsigned int len);
260
-
261
- /* The cache directory, or a negative MARS_XLOG_ERR_* code. */
262
- int mars_xlog_current_log_cache_path(char* out, unsigned int len);
263
-
225
+ int mars_xlog_getfilepath_from_timespan_instance(long long instance,
226
+ int timespan,
227
+ unsigned int index,
228
+ char* out,
229
+ unsigned int len);
230
+
231
+ /* The directory the appender of `instance` is writing its files to, or a negative
232
+ * MARS_XLOG_ERR_* code. A directory and not a file, which is what the C++'s
233
+ * `XloggerAppender::GetCurrentLogPath` answers — `sg_logdir`. A handle no
234
+ * appender is open for — `0` among them, since no symbol of this ABI installs
235
+ * a process-wide one — answers MARS_XLOG_ERR_NO_PATH. */
236
+ int mars_xlog_current_log_path_instance(long long instance, char* out, unsigned int len);
237
+
238
+ #ifdef __cplusplus
239
+ } /* extern "C" */
240
+ #endif
264
241
 
265
242
  #endif /* MARS_XLOG_H_ */
@@ -27,9 +27,13 @@
27
27
  * caller can include it without running cbindgen. It is kept in sync with
28
28
  * `src/abi.rs` by `tests/header_sync.rs`.
29
29
  *
30
- * Threading: every symbol may be called from any thread. `mars_xlog_open`,
31
- * `mars_xlog_close` and the setters mutate process-wide state (exactly like the
32
- * C++ globals) and should be called from one place during start-up / shut-down.
30
+ * Threading: every symbol may be called from any thread. The setters and the
31
+ * instance lifecycle mutate shared state (exactly like the C++ globals) and
32
+ * should be called from one place during start-up / shut-down. What no symbol
33
+ * here does is install a process-wide appender: an app opens an instance with
34
+ * `mars_xlog_new_instance` and writes through the handle it answers. Handle
35
+ * `0` names no appender at all — it is what an open that failed answers, and
36
+ * every symbol asked of it is a no-op.
33
37
  *
34
38
  * Panics: no Rust panic ever crosses this boundary. Every entry point is
35
39
  * wrapped in `catch_unwind`; a panic is reported as `MARS_XLOG_ERR_PANIC` (or
@@ -39,6 +43,17 @@
39
43
  #ifndef MARS_XLOG_H_
40
44
  #define MARS_XLOG_H_
41
45
 
46
+ /* The symbols this header declares are the ones `#[no_mangle]` exports: plain
47
+ * C names, and a C++ translation unit that includes this and calls
48
+ * `mars_xlog_new_instance()` asks its linker for a mangled one that does not
49
+ * exist.
50
+ * `mars_stn.h` and `mars_sdt.h` carry the same guard, and `mars_xlog.hpp` —
51
+ * the C++ face of this seam — includes this one, so a C++ caller asks for the
52
+ * same names whichever of the two it takes. */
53
+ #ifdef __cplusplus
54
+ extern "C" {
55
+ #endif
56
+
42
57
  /* --- enums ------------------------------------------------------------- */
43
58
 
44
59
  /** Mirrors `mars::xlog::TAppenderMode` (appender.h). */
@@ -60,8 +75,14 @@ typedef enum {
60
75
  /** Additional level understood only by the filter: disables every record. */
61
76
  #define MARS_LEVEL_NONE 6
62
77
 
63
- /* --- return codes ------------------------------------------------------- */
64
-
78
+ /* --- return codes -------------------------------------------------------
79
+ *
80
+ * The five from `NULL_CONFIG` to `APPENDER` are the reasons an open may be
81
+ * refused, and no symbol hands them out: `mars_xlog_new_instance` answers the
82
+ * handle `0` for every one of them, there being no room in a handle for a
83
+ * negative code. They are here for the caller that wants to name the reason in
84
+ * its own diagnostic, not to switch on an answer.
85
+ */
65
86
  #define MARS_XLOG_OK 0
66
87
  #define MARS_XLOG_ERR_NULL_CONFIG (-1) /* `config` was NULL */
67
88
  #define MARS_XLOG_ERR_BAD_MODE (-2) /* `mode` outside MarsAppenderMode */
@@ -73,17 +94,6 @@ typedef enum {
73
94
  #define MARS_XLOG_ERR_NO_PATH (-8) /* no current log file is open */
74
95
  #define MARS_XLOG_ERR_PANIC (-99) /* a Rust panic was caught at the boundary */
75
96
 
76
- /* --- `mars_xlog_oneshot_flush` result: mars::xlog::TFileIOAction --------- */
77
-
78
- #define MARS_XLOG_ACTION_NONE 0
79
- #define MARS_XLOG_ACTION_SUCCESS 1
80
- #define MARS_XLOG_ACTION_UNNECESSARY 2 /* there was nothing to flush */
81
- #define MARS_XLOG_ACTION_OPEN_FAILED 3
82
- #define MARS_XLOG_ACTION_READ_FAILED 4
83
- #define MARS_XLOG_ACTION_WRITE_FAILED 5
84
- #define MARS_XLOG_ACTION_CLOSE_FAILED 6
85
- #define MARS_XLOG_ACTION_REMOVE_FAILED 7
86
-
87
97
  /* --- config ------------------------------------------------------------- */
88
98
 
89
99
  /**
@@ -95,7 +105,7 @@ typedef enum {
95
105
  typedef struct {
96
106
  int mode; /* MarsAppenderMode; default when unset: Async */
97
107
  const char* log_dir; /* mandatory, directory is created if missing */
98
- const char* name_prefix; /* used verbatim; no default, as in C++ */
108
+ const char* name_prefix; /* used verbatim; no default; "" is refused */
99
109
  const char* pub_key; /* NULL / "" => logs are written unencrypted */
100
110
  int compress_mode; /* MarsCompressMode; default when unset: Zlib */
101
111
  int compress_level; /* <= 0 => keep the appender default (6) */
@@ -103,79 +113,44 @@ typedef struct {
103
113
  int cache_days; /* < 0 => 0; 0 => keep every file */
104
114
  } MarsXLogConfig;
105
115
 
106
- /* --- lifecycle ---------------------------------------------------------- */
107
-
108
- /**
109
- * Replaces `mars::xlog::appender_open(const XLogConfig&)`.
110
- *
111
- * @return MARS_XLOG_OK (0) on success, or a negative MARS_XLOG_ERR_* code.
112
- */
113
- int mars_xlog_open(const MarsXLogConfig* config);
114
-
115
- /**
116
- * Replaces `mars::xlog::XloggerWrite(...)` / `appender_write`. The record is
117
- * dropped (cheaply, before any formatting) when `level` is below the level set
118
- * by `mars_xlog_set_level`.
119
- *
120
- * `tag`, `filename`, `func_name` and `message` may be NULL; NULL and invalid
121
- * UTF-8 are treated as an empty string.
122
- */
123
- void mars_xlog_write(int level,
124
- const char* tag,
125
- const char* filename,
126
- const char* func_name,
127
- int line,
128
- const char* message);
129
-
130
- /** Replaces `mars::xlog::appender_flush()` — signals the writer thread. */
131
- void mars_xlog_flush(void);
132
-
133
- /** Replaces `mars::xlog::appender_flush_sync()` — flushes and waits. */
134
- void mars_xlog_flush_sync(void);
135
-
136
- /** Replaces `mars::xlog::appender_close()`. */
137
- void mars_xlog_close(void);
138
-
139
- /** Replaces `xlogger_SetLevel()`; `level` < 0 clamps to Verbose. */
140
- void mars_xlog_set_level(int level);
141
-
142
- /** Replaces `appender_set_console_log(bool)`; `open` != 0 means on. */
143
- void mars_xlog_set_console_log(int open);
144
-
145
- /** Replaces `appender_set_max_file_size(uint64_t)`; 0 means "do not split". */
146
- void mars_xlog_set_max_file_size(unsigned long long bytes);
147
-
148
- /** Replaces `appender_set_max_alive_duration(long)`; negative clamps to 0. */
149
- void mars_xlog_set_max_alive_duration(long long seconds);
150
-
151
- /**
152
- * Replaces `appender_get_current_log_path(char*, unsigned int)`.
153
- *
154
- * Writes the NUL-terminated path of the log file currently being appended to
155
- * into `out` (which must hold at least `len` bytes).
156
- *
157
- * @return the number of bytes written excluding the terminating NUL, or a
158
- * negative MARS_XLOG_ERR_* code (`MARS_XLOG_ERR_NULL_OUT`,
159
- * `MARS_XLOG_ERR_NO_SPACE`, `MARS_XLOG_ERR_NO_PATH`).
160
- */
161
- int mars_xlog_current_log_path(char* out, unsigned int len);
162
-
163
116
  /* ---- logger instances (mars::xlog::NewXloggerInstance and friends) ----
164
117
  *
165
118
  * Each instance owns an appender: its own log directory, prefix, key, mode and
166
- * cache file. Handle 0 means "the process-wide appender opened by
167
- * mars_xlog_open".
119
+ * cache file. A C caller that wants a logger opens one with
120
+ * mars_xlog_new_instance and holds the handle it answers.
121
+ *
122
+ * Every call that can be asked of an instance exists only in this spelling:
123
+ * the C++ has a free function for its process-wide appender and a
124
+ * handle-taking one beside it, and a second spelling of the same operation
125
+ * here would be two ways to say one thing. There is no process-wide appender
126
+ * to install, so there is no free-function spelling either — and handle `0`,
127
+ * which is what a failed open answers, names no appender: the level, the mode,
128
+ * the console, the two sizes and the drain asked of it do nothing, and the
129
+ * questions answer "no" or `MARS_XLOG_ERR_NO_PATH`.
168
130
  */
169
131
 
132
+ /* --- writing ------------------------------------------------------------- */
133
+
170
134
  /* Returns the instance handle, or 0 on a null/invalid config. */
171
135
  long long mars_xlog_new_instance(const MarsXLogConfig* config, int level);
172
136
 
173
137
  /* The handle registered for name_prefix, or 0 when there is none. */
174
138
  long long mars_xlog_get_instance(const char* name_prefix);
175
139
 
176
- /* Releases the instance and closes its appender. */
140
+ /* Releases the instance and closes its appender. Prefer the handle-aware
141
+ * mars_xlog_release_instance_of() when the caller holds an instance handle. */
177
142
  void mars_xlog_release_instance(const char* name_prefix);
178
143
 
144
+ /* The same, and only while name_prefix is still registered under `instance`.
145
+ *
146
+ * Releasing takes the prefix and not the handle, so asking
147
+ * mars_xlog_get_instance and then calling mars_xlog_release_instance is two
148
+ * answers and not one: an open of the same prefix that lands between the two is
149
+ * handed a handle of its own, and the release closes that one. This is the
150
+ * question and the release in one call, which is also what makes a second
151
+ * close of a prefix a no-op however many callers hold its handle. */
152
+ void mars_xlog_release_instance_of(const char* name_prefix, long long instance);
153
+
179
154
  /* Writes through an instance; honours the instance's level. */
180
155
  void mars_xlog_write_instance(long long instance,
181
156
  int level,
@@ -191,22 +166,31 @@ int mars_xlog_is_enabled_for(long long instance, int level);
191
166
  /* The instance's level, or -1 for an unknown handle. */
192
167
  int mars_xlog_get_level(long long instance);
193
168
 
194
- /* SetLevel for an instance (0 = the default logger). */
169
+ /* SetLevel for an instance: the level `mars_xlog_get_level` and
170
+ * `mars_xlog_is_enabled_for` answer, and the one a write through the same
171
+ * handle asks. A no-op for handle `0`, which is no instance at all. */
195
172
  void mars_xlog_set_level_instance(long long instance, int level);
196
173
 
197
- /* appender_setmode: switches the process-wide appender between async/sync. */
198
- void mars_xlog_set_mode(int mode);
199
-
200
- /* SetAppenderMode for an instance. */
174
+ /* appender_setmode / SetAppenderMode for an instance. */
201
175
  void mars_xlog_set_mode_instance(long long instance, int mode);
202
176
 
203
- /* Drains an instance; sync != 0 waits for the write to complete. */
204
- void mars_xlog_flush_instance(long long instance, int sync);
205
-
206
- /* FlushAll: drains the process-wide appender *and* every instance. */
207
- void mars_xlog_flush_all(int sync);
208
-
209
- /* SetConsoleLogOpen for an instance (0 = the default logger). */
177
+ /* Drains an instance, requested: the writer thread is told it may drain, and
178
+ * this returns at once. Nothing is in the file because this returned, and
179
+ * nothing answers when the drain is over. The C++'s name for this call is
180
+ * `appender_flush`, and "flush" there said which mode the appender was opened
181
+ * in and not what the call does to the thread it was called on: the port names
182
+ * the drain by what the caller gets back, and what this one gives is no answer
183
+ * at all — hence "request", which is the one thing the two drains that do
184
+ * answer, `mars_xlog_flush_now_instance` and the awaited `flush()` every
185
+ * platform carries, do give. */
186
+ void mars_xlog_request_flush_instance(long long instance);
187
+
188
+ /* Drains an instance on the calling thread, which is what
189
+ * `appender_flush_sync` is: its records are on the disk when this returns, and
190
+ * that is a promise the requested call above does not make. */
191
+ void mars_xlog_flush_now_instance(long long instance);
192
+
193
+ /* SetConsoleLogOpen for an instance. */
210
194
  void mars_xlog_set_console_log_instance(long long instance, int open);
211
195
 
212
196
  /* SetMaxFileSize for an instance; 0 means "do not split". */
@@ -215,51 +199,44 @@ void mars_xlog_set_max_file_size_instance(long long instance, unsigned long long
215
199
  /* SetMaxAliveTime for an instance; negative clamps to 0. */
216
200
  void mars_xlog_set_max_alive_duration_instance(long long instance, long long seconds);
217
201
 
218
- /**
219
- * Replaces `mars::xlog::appender_oneshot_flush()`: drains the
220
- * `<prefix>[_<n>].mmap3` cache files another process left behind, without
221
- * opening an appender. The ones a live writer of this process — or of any
222
- * other — still holds are left alone, so it answers
223
- * MARS_XLOG_ACTION_UNNECESSARY when there is nothing of a dead process's to
224
- * recover.
225
- *
226
- * @return one of the MARS_XLOG_ACTION_* values (0..7), or a negative
227
- * MARS_XLOG_ERR_* code when `config` is unusable.
228
- */
229
- int mars_xlog_oneshot_flush(const MarsXLogConfig* config);
230
-
231
202
  /**
232
203
  * Replaces `mars::xlog::appender_make_logfile_name()`: the log file *name* for
233
204
  * the day `timespan` days ago (0 = today), whether or not it exists yet.
234
205
  *
235
206
  * The C++ fills a `std::vector`; a C caller walks the same list with `index`,
236
- * starting at 0 and stopping at MARS_XLOG_ERR_NO_PATH. `prefix` and `log_dir`
237
- * may be NULL (an empty `log_dir` yields no name at all).
207
+ * starting at 0 and stopping at MARS_XLOG_ERR_NO_PATH. `instance` is a handle
208
+ * from `mars_xlog_new_instance`; a handle no appender is open for answers
209
+ * MARS_XLOG_ERR_NO_PATH from the first index.
238
210
  *
239
211
  * @return the number of bytes written excluding the terminating NUL, or a
240
212
  * negative MARS_XLOG_ERR_* code.
241
213
  */
242
- int mars_xlog_make_logfile_name(int timespan,
243
- const char* prefix,
244
- const char* log_dir,
245
- unsigned int index,
246
- char* out,
247
- unsigned int len);
214
+ int mars_xlog_make_logfile_name_instance(long long instance,
215
+ int timespan,
216
+ unsigned int index,
217
+ char* out,
218
+ unsigned int len);
248
219
 
249
220
  /**
250
221
  * Replaces `mars::xlog::appender_getfilepath_from_timespan()`: the log files
251
222
  * that *exist* for the day `timespan` days ago. Same `index` protocol as
252
- * mars_xlog_make_logfile_name.
223
+ * mars_xlog_make_logfile_name_instance.
253
224
  */
254
- int mars_xlog_getfilepath_from_timespan(int timespan,
255
- const char* prefix,
256
- const char* log_dir,
257
- unsigned int index,
258
- char* out,
259
- unsigned int len);
260
-
261
- /* The cache directory, or a negative MARS_XLOG_ERR_* code. */
262
- int mars_xlog_current_log_cache_path(char* out, unsigned int len);
263
-
225
+ int mars_xlog_getfilepath_from_timespan_instance(long long instance,
226
+ int timespan,
227
+ unsigned int index,
228
+ char* out,
229
+ unsigned int len);
230
+
231
+ /* The directory the appender of `instance` is writing its files to, or a negative
232
+ * MARS_XLOG_ERR_* code. A directory and not a file, which is what the C++'s
233
+ * `XloggerAppender::GetCurrentLogPath` answers — `sg_logdir`. A handle no
234
+ * appender is open for — `0` among them, since no symbol of this ABI installs
235
+ * a process-wide one — answers MARS_XLOG_ERR_NO_PATH. */
236
+ int mars_xlog_current_log_path_instance(long long instance, char* out, unsigned int len);
237
+
238
+ #ifdef __cplusplus
239
+ } /* extern "C" */
240
+ #endif
264
241
 
265
242
  #endif /* MARS_XLOG_H_ */
package/ios/Xlog.mm CHANGED
@@ -5,7 +5,7 @@
5
5
  // and jsi types. Neither has a Swift spelling: Swift's C++ interop stops at
6
6
  // templates and at the standard library. So what is here is the three things
7
7
  // React Native asks a module for and cannot read out of `Xlog.swift`, and the
8
- // eleven methods are there and not here.
8
+ // sixteen methods are there and not here.
9
9
  //
10
10
  // * `RCT_EXTERN_MODULE` registers the Swift class, which Swift cannot do for
11
11
  // itself — registration is a constructor the runtime runs, and a Swift class
@@ -18,7 +18,7 @@
18
18
  // * `methodQueue` answers `RCTJSThread`, the queue that is no queue: it is
19
19
  // what makes a TurboModule's methods run on the JS thread, so a call is made
20
20
  // where it is asked for and a method that answers a value answers it before
21
- // it returns. Without it the eleven would be dispatched to a queue of the
21
+ // it returns. Without it the sixteen would be dispatched to a queue of the
22
22
  // module's own and every answer would arrive as `undefined`.
23
23
  //
24
24
  // Objective-C++, and not Objective-C, because of the one `#include` a Swift