aboutsummaryrefslogtreecommitdiffstats
path: root/man/rb_destroy.3
blob: e88d499f8fb4c530f06fddd6fcf7627909661d98 (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
.TH "rb_destroy" "3" " 9 February 2018 (v1.0.0)" "bofc.pl"
.SH NAME
.PP
.B rb_destroy,
.B rb_stop
- functions to stop any locked threads in rb functions and free resources
allocated by
.BR rb_new (3)
.SH SYNOPSIS
.PP
.BI "int rb_stop(struct rb *" rb ");"
.br
.BI "int rb_destroy(struct rb *" rb ");"
.SH DESCRIPTION
.PP
Function
.BR rb_stop (3)
spawns thread (and then exits) that forces any locked thread to exit from
.BR rb_read (3)
or
.BR rb_send (3).
Also after this function is called, any call to
.BR rb_read (3)
or
.BR rb_send (3)
will result in error.
.PP
Function
.BR rb_destroy (3)
simply frees all resources allocated by
.BR rb_new (3).
If
.BR rb_stop (3)
was called before, function will stop spawned thread.
After calling this,
.I rb
that was freed, cannot be used anymore without calling
.BR rb_new (3)
first.
Passing same
.I rb
object twice, will result in segmentation fault.
.SH NOTES
.PP
Due to nature of pthread, you must be sure that no threads are calling
any functions from
.B librb
before calling
.BR rb_destroy (3).
Failing to do so, will lead to deadlocks or crashes sooner or later.
.PP
If you cannot stop threads by yourself before calling
.BR rb_destroy (3),
you can use
.BR rb_stop (3)
function, to force all threads to exit, then join them, and after that destroy
.I rb
object.
Look at below example.
.PP
.EX
    void *consumer(void *arg)
    {
        struct rb *rb = arg;
        int v, e;
        if (rb_read(rb, &v, 1) != 0)
        {
            if (errno == ECANCELED)
            {
                /* function was forced to exit, we should stop thread
                 * or at least make sure we don't access rb_* functions
                 * anymore
                 /

                 return NULL;
            }
        }
        /* more code */
    }

    void foo(void)
    {
        /* some code */
        for (int i = 0; i != 10; ++i)
        {
            pthread_create(&consumers[i], NULL, consumer, rb);
        }

        /* wait for some event */
        /* force all consumer threads to exit even if they are locked
         * in some conditional variables
         */
        rb_stop(rb);

        for (i = 0; i != 10; ++i)
        {
            /* make sure all consumer threads stopped, and none will access
             * any rb_* functions
             /
            pthread_join(consumers[i], NULL);
        }

        /* now it is safe to call rb_destroy function */
        rb_destroy(rb);
    }
.EE
.SH RETURN VALUES
.PP
Function will return 0 when all resources were freed, otherwise -1 is returned.
If function returns -1
.I rb
object is not modified.
.SH ERRORS
.TP
.B EINVAL
Passed
.I rb
is invalid (null).
.SH SEE ALSO
.PP
.BR rb_overview (7),
.BR rb_new (3),
.BR rb_read (3),
.BR rb_discard (3),
.BR rb_recv (3),
.BR rb_write (3),
.BR rb_send (3),
.BR rb_clear (3),
.BR rb_count (3),
.BR rb_space (3),
.BR rb_version (3)