<a id="h-threaded-writer"></a>

# JLS Threaded Writer

### *group* Threaded writer

JLS threaded writer. 

This module wraps writer. For normal operation while recording signals, prefer this threaded writer over writer.

Errors: each call validates its arguments synchronously, and a validation error changes nothing. The writer thread performs the writes, so their errors are asynchronous. The first asynchronous error latches: the thread keeps draining its queue but drops all data messages, and every later jls_twr_\* call, [jls_twr_flush()](#group__jls__threaded__writer_1ga33f0a438d9190e3559bac9cdef8d10e1), and [jls_twr_close()](#group__jls__threaded__writer_1gac65f980f0596fded7ccce711aa8e9cfd) returns the latched error. Call [jls_twr_flush()](#group__jls__threaded__writer_1ga33f0a438d9190e3559bac9cdef8d10e1) to confirm that all queued writes succeeded. 

### Enums

### enum jls_twr_flag_e

The threaded writer flags. 

*Values:*

### enumerator JLS_TWR_FLAG_DROP_ON_OVERFLOW

Drop on overflow when set, block otherwise. 

### Functions

### int32_t jls_twr_open(struct jls_twr_s \*\*instance, const char \*path)

Open a JLS file for writing. 


Call [jls_twr_close()](#group__jls__threaded__writer_1gac65f980f0596fded7ccce711aa8e9cfd) when done. 

* **Parameters:**
  * **instance** – **[out]** The JLS writer instance. 
  * **path** – The JLS file path. 
* **Returns:**
  0 or error code.

### int32_t jls_twr_close(struct jls_twr_s \*self)

Close a JLS file. 


Close writes all queued messages before closing the file, even when the queue is full. After a latched error, the queued data messages are dropped and the file is left not properly closed, so [jls_rd_open()](https://docs.joulescope.com/en/software/jls/h_reader.md#group__jls__reader_1ga6ca4acb977c6409f2b5b879a8e505a8b) recovers the data written before the error. See jls_wr_close(). 

* **Parameters:**
  **self** – The JLS writer instance from [jls_twr_open()](#group__jls__threaded__writer_1ga64dffbcf6d77962d466a5cc21d4e15c7), which is always freed. 
* **Returns:**
  0, the latched error, or the jls_wr_close() error.

### uint32_t jls_twr_flags_get(struct jls_twr_s \*self)

* **Parameters:**
  * **Get** – threaded writer flags.
  * **self** – The JLS writer instance from [jls_twr_open()](#group__jls__threaded__writer_1ga64dffbcf6d77962d466a5cc21d4e15c7). 
  * **flags** – The [jls_twr_flag_e](#group__jls__threaded__writer_1gac291e93617bd900bc18978013d830192) bits. 
* **Returns:**
  0 or error code. 

### int32_t jls_twr_flags_set(struct jls_twr_s \*self, uint32_t flags)

* **Parameters:**
  * **Set** – threaded writer flags.
  * **self** – The JLS writer instance from [jls_twr_open()](#group__jls__threaded__writer_1ga64dffbcf6d77962d466a5cc21d4e15c7). 
  * **flags** – The [jls_twr_flag_e](#group__jls__threaded__writer_1gac291e93617bd900bc18978013d830192) bits. 
* **Returns:**
  0 or error code. 

### int32_t jls_twr_flush(struct jls_twr_s \*self)

Flush a JLS file to disk. 


See jls_wr_flush() for the durability provided. 

* **Parameters:**
  **self** – The JLS writer instance from [jls_twr_open()](#group__jls__threaded__writer_1ga64dffbcf6d77962d466a5cc21d4e15c7). 
* **Returns:**
  0 when all previously queued messages were written and flushed, the latched error, JLS_ERROR_BUSY if the flush could not be queued, or JLS_ERROR_TIMED_OUT.

### int32_t jls_twr_source_def(struct jls_twr_s \*self, const struct [jls_source_def_s](https://docs.joulescope.com/en/software/jls/h_format.md#_CPPv416jls_source_def_s) \*source)

Define a new source. 


This JLS file format supports multiple sources, which are usually different instruments. Each source can provide multiple signals. 

* **Parameters:**
  * **self** – The JLS writer instance. 
  * **source** – The source definition. 
* **Returns:**
  0 or error code.

### int32_t jls_twr_signal_def(struct jls_twr_s \*self, const struct [jls_signal_def_s](https://docs.joulescope.com/en/software/jls/h_format.md#_CPPv416jls_signal_def_s) \*signal)

Define a new signal. 

* **Parameters:**
  * **self** – The JLS writer instance. 
  * **signal** – The signal definition. 
* **Returns:**
  0 or error code. 

### int32_t jls_twr_user_data(struct jls_twr_s \*self, uint16_t chunk_meta, enum [jls_storage_type_e](https://docs.joulescope.com/en/software/jls/h_format.md#_CPPv418jls_storage_type_e) storage_type, const uint8_t \*data, uint32_t data_size)

Add arbitrary user data. 

* **Parameters:**
  * **self** – The writer instance. 
  * **chunk_meta** – The arbitrary data. Bits 15:12 are reserved and must be 0 (else JLS_ERROR_PARAMETER_INVALID), but bits 11:0 may be assigned by the application. 
  * **storage_type** – The storage type for data, which must be a [jls_storage_type_e](https://docs.joulescope.com/en/software/jls/h_format.md#group__jls__format_1ga8b5a75849f337b751c2b844039c45e4a) value. 
  * **data** – The user data to store. 
  * **data_size** – The size of data in bytes. For STRING and JSON, 0 means strlen(data) + 1, and a nonzero size must include the NUL. 
* **Returns:**
  0 or error code. JLS_ERROR_TOO_BIG when the message exceeds the internal queue. 

### int32_t jls_twr_fsr(struct jls_twr_s \*self, uint16_t signal_id, int64_t sample_id, const void \*data, uint32_t data_length)

Write fixed-rate sample data to a signal. 

* **Parameters:**
  * **self** – The JLS writer instance. 
  * **signal_id** – The signal id. 
  * **sample_id** – The sample id for data[0]. 
  * **data** – The sample data array. Data must be packed with no spacing between samples. u1 stores 8 samples per byte, and u4 stores 2 samples per byte. 
  * **data_length** – The length of data in samples. 
* **Returns:**
  0 or error code. JLS_ERROR_TOO_BIG when the data exceeds the internal queue (about 64 MiB). 

### int32_t jls_twr_fsr_f32(struct jls_twr_s \*self, uint16_t signal_id, int64_t sample_id, const float \*data, uint32_t data_length)

Write sample data to a float32 FSR signal. 

* **Parameters:**
  * **self** – The JLS writer instance. 
  * **signal_id** – The signal id. 
  * **sample_id** – The sample id for data[0]. 
  * **data** – The sample data array. 
  * **data_length** – The length of data in floats (bytes / 4). 
* **Returns:**
  0 or error code 

### int32_t jls_twr_fsr_omit_data(struct jls_twr_s \*self, uint16_t signal_id, uint32_t enable)

Omit level 0 data chunks from the signal’s stream. 


Enable is delayed by one sample block to ensure any pending data is writen. Disable takes effect immediately.

On read, the level 0 data is reconstructed using the summaries.

When enabled, the writer omits a data chunk only when the signal’s data type is 8 bits or less (u1, u4, u8, i4, i8) and every sample in the chunk has the same value. The setting has no effect on other data types. 

* **Parameters:**
  * **self** – The JLS writer instance 
  * **signal_id** – The signal id. 
  * **enable** – 0 to disable (default), 1 to enable. 
* **Returns:**
  0 or error code.

### int32_t jls_twr_annotation(struct jls_twr_s \*self, uint16_t signal_id, int64_t timestamp, float y, enum [jls_annotation_type_e](https://docs.joulescope.com/en/software/jls/h_format.md#_CPPv421jls_annotation_type_e) annotation_type, uint8_t group_id, enum [jls_storage_type_e](https://docs.joulescope.com/en/software/jls/h_format.md#_CPPv418jls_storage_type_e) storage_type, const uint8_t \*data, uint32_t data_size)

Add an annotation to a signal. 

* **Parameters:**
  * **self** – The writer instance. 
  * **signal_id** – The signal id. 
  * **timestamp** – The x-axis timestamp in sample_id for FSR and UTC for VSR. 
  * **y** – The y-axis value or NAN to automatically position. 
  * **annotation_type** – The annotation type. 
  * **group_id** – The optional group identifier. If unused, set to 0. 
  * **storage_type** – The storage type. 
  * **data** – The data for the annotation. 
  * **data_size** – The length of data in bytes. For STRING and JSON, 0 means strlen(data) + 1, and a nonzero size must include the NUL. 
* **Returns:**
  0 or error code. JLS_ERROR_TOO_BIG when the message exceeds the internal queue. 

### int32_t jls_twr_utc(struct jls_twr_s \*self, uint16_t signal_id, int64_t sample_id, int64_t utc)

Add a mapping from sample_id to UTC timestamp for an FSR signal. 

* **Parameters:**
  * **self** – The writer instance. 
  * **signal_id** – The signal id. 
  * **sample_id** – The sample_id for FSR. 
  * **utc** – The UTC timestamp. 
* **Returns:**
  0 or error code.
