blob: 1f5f2de085613a94e75ac018555093e275a251d2 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file lock/lock.c Pthread mutex locking
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#define _DEFAULT_SOURCE 1
7#define __USE_UNIX98 1
8#include <pthread.h>
9#include <re_types.h>
10#include <re_mem.h>
11#include <re_lock.h>
12
13
14#define DEBUG_MODULE "lock"
15#define DEBUG_LEVEL 5
16#include <re_dbg.h>
17
18
19#ifndef RELEASE
20#define LOCK_DEBUG 0
21#endif
22
23
24/** Defines a lock */
25struct lock {
26 pthread_mutex_t m;
27};
28
29
30static void lock_destructor(void *data)
31{
32 struct lock *l = data;
33
34 int err = pthread_mutex_destroy(&l->m);
35 if (err) {
36 DEBUG_WARNING("pthread_mutex_destroy: %m\n", err);
37 }
38}
39
40
41/**
42 * Allocate a new lock
43 *
44 * @param lp Pointer to allocated lock object
45 *
46 * @return 0 if success, otherwise errorcode
47 */
48int lock_alloc(struct lock **lp)
49{
50 pthread_mutexattr_t attr;
51 struct lock *l;
52
53 if (!lp)
54 return EINVAL;
55
56 l = mem_zalloc(sizeof(*l), lock_destructor);
57 if (!l)
58 return ENOMEM;
59
60 (void)pthread_mutex_init(&l->m, NULL);
61
62 pthread_mutexattr_init(&attr);
63
64#if LOCK_DEBUG
65 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
66 DEBUG_NOTICE("init debug lock\n");
67#else
68 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
69#endif
70 pthread_mutex_init(&l->m, &attr);
71
72 *lp = l;
73 return 0;
74}
75
76
77/**
78 * Get the lock for reading
79 *
80 * @param l Lock object
81 */
82void lock_read_get(struct lock *l)
83{
84 const int err = pthread_mutex_lock(&l->m);
85 if (err) {
86 DEBUG_WARNING("lock_read_get: %m\n", err);
87 }
88}
89
90
91/**
92 * Get the lock for writing
93 *
94 * @param l Lock object
95 */
96void lock_write_get(struct lock *l)
97{
98 const int err = pthread_mutex_lock(&l->m);
99 if (err) {
100 DEBUG_WARNING("lock_write_get: %m\n", err);
101 }
102}
103
104
105/**
106 * Attempt to get a lock for reading
107 *
108 * @param l Lock object
109 *
110 * @return 0 if success, otherwise errorcode
111 */
112int lock_read_try(struct lock *l)
113{
114 return pthread_mutex_trylock(&l->m);
115}
116
117
118/**
119 * Attempt to get a lock for writing
120 *
121 * @param l Lock object
122 *
123 * @return 0 if success, otherwise errorcode
124 */
125int lock_write_try(struct lock *l)
126{
127 return pthread_mutex_trylock(&l->m);
128}
129
130
131/**
132 * Release a lock
133 *
134 * @param l Lock object
135 */
136void lock_rel(struct lock *l)
137{
138 const int err = pthread_mutex_unlock(&l->m);
139 if (err) {
140 DEBUG_WARNING("lock_rel: %m\n", err);
141 }
142}