summaryrefslogtreecommitdiff
path: root/man/mpu_unlocked.3
blob: ef087103673975a32f7f1b23102dd7023dad5f91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
.TH MPU_UNLOCKED 3 "August 2026" "libmpuio" "LIBMPUIO Programmer's Manual"
.SH NAME
mpu_unlocked \- LIBMPUIO operations that omit implicit stream locking
.SH LIBRARY
LIBMPUIO companion library for LIBMPU.
.SH SYNOPSIS
.nf
#include <libmpuio.h>

int             mpu_fgetc_unlocked( mpu_FILE *stream );
int             mpu_getc_unlocked( mpu_FILE *stream );
int             mpu_getchar_unlocked( void );
int             mpu_fputc_unlocked( __mpu_char16_t c, mpu_FILE *stream );
int             mpu_putc_unlocked( __mpu_char16_t c, mpu_FILE *stream );
int             mpu_putchar_unlocked( __mpu_char16_t c );
__mpu_char16_t *mpu_fgets_unlocked( __mpu_char16_t *s, int n,
                                    mpu_FILE *stream );
int             mpu_fputs_unlocked( const __mpu_char16_t *s, mpu_FILE *stream );
ssize_t         mpu_getdelim_unlocked( __mpu_char16_t **lineptr, size_t *n,
                                       __mpu_char16_t delimiter,
                                       mpu_FILE *stream );
ssize_t         mpu_getline_unlocked( __mpu_char16_t **lineptr, size_t *n,
                                      mpu_FILE *stream );

size_t          mpu_fread_unlocked( void *ptr, size_t size, size_t nmemb,
                                    mpu_FILE *stream );
size_t          mpu_fwrite_unlocked( const void *ptr, size_t size, size_t nmemb,
                                     mpu_FILE *stream );
int             mpu_fflush_unlocked( mpu_FILE *stream );
int             mpu_fpurge_unlocked( mpu_FILE *stream );

int             mpu_vfprintf_unlocked( mpu_FILE *stream,
                                       const __mpu_char16_t *format, va_list args );
int             mpu_fprintf_unlocked( mpu_FILE *stream,
                                      const __mpu_char16_t *format, ... );
int             mpu_vprintf_unlocked( const __mpu_char16_t *format, va_list args );
int             mpu_printf_unlocked( const __mpu_char16_t *format, ... );

int             mpu_vfscanf_unlocked( mpu_FILE *stream,
                                      const __mpu_char16_t *format, va_list args );
int             mpu_fscanf_unlocked( mpu_FILE *stream,
                                     const __mpu_char16_t *format, ... );
int             mpu_vscanf_unlocked( const __mpu_char16_t *format, va_list args );
int             mpu_scanf_unlocked( const __mpu_char16_t *format, ... );

int             mpu_fileno_unlocked( mpu_FILE *stream );
int             mpu_feof_unlocked( mpu_FILE *stream );
int             mpu_ferror_unlocked( mpu_FILE *stream );
void            mpu_clearerr_unlocked( mpu_FILE *stream );
.fi
.SH DESCRIPTION
Every function listed here performs the same logical operation as its ordinary
counterpart but does not acquire or release the stream mutex.
.PP
This is analogous to the unlocked stdio family in libc.  It is primarily useful
for batching multiple operations under one explicit lock, avoiding repeated
lock/unlock overhead while preserving atomicity with respect to other users of
the same stream.
.SH LOCKED VERSUS UNLOCKED
.TS
allbox tab(:);
l l l.
Operation:Locked form:Unlocked form
character input:mpu_fgetc/mpu_getc/mpu_getchar:mpu_fgetc_unlocked/mpu_getc_unlocked/mpu_getchar_unlocked
character output:mpu_fputc/mpu_putc/mpu_putchar:mpu_fputc_unlocked/mpu_putc_unlocked/mpu_putchar_unlocked
string input/output:mpu_fgets/mpu_fputs:mpu_fgets_unlocked/mpu_fputs_unlocked
raw binary:mpu_fread/mpu_fwrite:mpu_fread_unlocked/mpu_fwrite_unlocked
flush:mpu_fflush:mpu_fflush_unlocked
purge:mpu_fpurge:mpu_fpurge_unlocked
formatted output:mpu_fprintf/mpu_printf + va_list forms:corresponding _unlocked forms
formatted input:mpu_fscanf/mpu_scanf + va_list forms:corresponding _unlocked forms
descriptor/status:mpu_fileno/mpu_feof/mpu_ferror:corresponding _unlocked forms
clear error:mpu_clearerr:mpu_clearerr_unlocked
.TE
.PP
There is intentionally no unlocked variant for operations such as
.BR mpu_fopen (),
.BR mpu_fdopen (),
.BR mpu_fclose (),
positioning, buffering configuration, or
.BR mpu_ungetc ().
Those APIs perform stream lifetime/state transitions for which the public API
provides only the synchronized form.
.PP
.BR mpu_sprintf (),
.BR mpu_snprintf (),
.BR mpu_sscanf ()
and their va_list forms operate on caller-owned UCS-2 memory rather than an
.B mpu_FILE
stream, so a stream-unlocked variant is unnecessary.
.SH REQUIRED CALLER DISCIPLINE
An unlocked call is safe only when no other thread can concurrently access the
same stream, or when the caller already owns the stream lock.
.PP
The normal pattern is:
.nf
mpu_flockfile( fp );
mpu_fputs_unlocked( text, fp );
mpu_fputc_unlocked( '\n', fp );
mpu_fflush_unlocked( fp );
mpu_funlockfile( fp );
.fi
.PP
The stream mutex is recursive, so calling an ordinary locked operation while
holding an explicit flock is valid, although using the unlocked counterpart is
usually the point of the explicit lock.
.SH IMPORTANT DIFFERENCES
.B mpu_fflush_unlocked()
requires a non-NULL stream and flushes only that stream.
.B mpu_fflush(NULL)
is the synchronized all-streams operation; NULL has no all-streams meaning for
the unlocked form.
.PP
.B mpu_fpurge_unlocked()
has exactly the same discard semantics as mpu_fpurge(), but assumes that the
caller already owns the stream lock or otherwise has exclusive access.
.PP
Unlocked formatted functions use exactly the same format grammar, MPU size
rules, count semantics, locale behavior, rollback rules, and errors as their
locked counterparts.  They differ only in implicit stream locking.
.PP
Unlocked raw I/O remains byte-oriented.  Unlocked text I/O remains strict
UCS-2 internally and UTF-8 at real-file boundaries.
.PP
The ordinary mpu_fileno() entry point acquires the stream mutex;
mpu_fileno_unlocked() reads the same descriptor state without acquiring it.
.SH RETURN VALUE
Exactly as documented for the corresponding ordinary function.
.SH ERRORS
Exactly as documented for the corresponding ordinary function.  The unlocked
property does not suppress validation or backend errors.
.SH THREAD SAFETY
Ordinary stream calls are internally synchronized.  Unlocked calls are not
safe for concurrent access to the same stream unless the application supplies
external synchronization.  Concurrent use of an unlocked operation and
.BR mpu_fclose ()
on the same stream without application synchronization is invalid.
.SH SEE ALSO
.BR libmpuio (3),
.BR mpu_flockfile (3),
.BR mpu_fgetc (3),
.BR mpu_fread (3),
.BR mpu_fpurge (3),
.BR mpu_printf (3),
.BR mpu_scanf (3)

.SH DYNAMIC LINE INPUT
.BR mpu_getline_unlocked ()
and
.BR mpu_getdelim_unlocked ()
have the same allocation, delimiter, EOF, UCS-2 validation, and return-value
semantics as their locked forms.  Only implicit acquisition of the stream mutex
is omitted.  The caller remains responsible for free(3) of the resulting buffer.