source: mainline/uspace/srv/logger/logs.c@ 1dec7cb

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1dec7cb was 1dec7cb, checked in by Vojtech Horky <vojtechhorky@…>, 13 years ago

Use lock/unlock naming

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * Copyright (c) 2012 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup logger
30 * @{
31 */
32#include <assert.h>
33#include <malloc.h>
34#include <str.h>
35#include <stdio.h>
36#include <errno.h>
37#include "logger.h"
38
39
40static FIBRIL_MUTEX_INITIALIZE(log_list_guard);
41static LIST_INITIALIZE(log_list);
42
43
44static logger_log_t *find_log_by_name_and_parent_no_list_lock(const char *name, logger_log_t *parent)
45{
46 list_foreach(log_list, it) {
47 logger_log_t *log = list_get_instance(it, logger_log_t, link);
48 if ((parent == log->parent) && (str_cmp(log->name, name) == 0))
49 return log;
50 }
51
52 return NULL;
53}
54
55static int create_dest(const char *name, logger_dest_t **dest)
56{
57 logger_dest_t *result = malloc(sizeof(logger_dest_t));
58 if (result == NULL)
59 return ENOMEM;
60 int rc = asprintf(&result->filename, "/log/%s", name);
61 if (rc < 0) {
62 free(result);
63 return ENOMEM;
64 }
65 result->logfile = NULL;
66 fibril_mutex_initialize(&result->guard);
67 *dest = result;
68 return EOK;
69}
70
71static logger_log_t *create_log_no_locking(const char *name, logger_log_t *parent)
72{
73 logger_log_t *result = calloc(1, sizeof(logger_log_t));
74 if (result == NULL)
75 return NULL;
76
77 result->name = str_dup(name);
78 if (result->name == NULL)
79 goto error;
80
81 /*
82 * Notice that we create new dest as the last
83 * operation that can fail and thus there is no code
84 * to deallocate dest.
85 */
86 if (parent == NULL) {
87 result->full_name = str_dup(name);
88 if (result->full_name == NULL)
89 goto error;
90 int rc = create_dest(name, &result->dest);
91 if (rc != EOK)
92 goto error;
93 } else {
94 int rc = asprintf(&result->full_name, "%s/%s",
95 parent->full_name, name);
96 if (rc < 0)
97 goto error;
98 result->dest = parent->dest;
99 }
100
101 /* Following initializations cannot fail. */
102 result->logged_level = LOG_LEVEL_USE_DEFAULT;
103 fibril_mutex_initialize(&result->guard);
104 link_initialize(&result->link);
105 result->parent = parent;
106
107 return result;
108
109error:
110 free(result->name);
111 free(result->full_name);
112 free(result);
113 return NULL;
114
115}
116
117logger_log_t *find_or_create_log_and_lock(const char *name, sysarg_t parent_id)
118{
119 logger_log_t *result = NULL;
120 logger_log_t *parent = (logger_log_t *) parent_id;
121
122 fibril_mutex_lock(&log_list_guard);
123
124 result = find_log_by_name_and_parent_no_list_lock(name, parent);
125 if (result == NULL) {
126 result = create_log_no_locking(name, parent);
127 if (result == NULL)
128 goto leave;
129 }
130
131 fibril_mutex_lock(&result->guard);
132
133 list_append(&result->link, &log_list);
134
135leave:
136 fibril_mutex_unlock(&log_list_guard);
137
138 return result;
139}
140
141logger_log_t *find_log_by_name_and_lock(const char *name)
142{
143 logger_log_t *result = NULL;
144
145 fibril_mutex_lock(&log_list_guard);
146 list_foreach(log_list, it) {
147 logger_log_t *log = list_get_instance(it, logger_log_t, link);
148 if (str_cmp(log->full_name, name) == 0) {
149 fibril_mutex_lock(&log->guard);
150 result = log;
151 break;
152 }
153 }
154 fibril_mutex_unlock(&log_list_guard);
155
156 return result;
157}
158
159logger_log_t *find_log_by_id_and_lock(sysarg_t id)
160{
161 logger_log_t *result = NULL;
162
163 fibril_mutex_lock(&log_list_guard);
164 list_foreach(log_list, it) {
165 logger_log_t *log = list_get_instance(it, logger_log_t, link);
166 if ((sysarg_t) log == id) {
167 fibril_mutex_lock(&log->guard);
168 result = log;
169 break;
170 }
171 }
172 fibril_mutex_unlock(&log_list_guard);
173
174 return result;
175}
176
177static log_level_t get_actual_log_level(logger_log_t *log)
178{
179 /* Find recursively proper log level. */
180 if (log->logged_level == LOG_LEVEL_USE_DEFAULT) {
181 if (log->parent == NULL)
182 return get_default_logging_level();
183 else
184 return get_actual_log_level(log->parent);
185 }
186 return log->logged_level;
187}
188
189bool shall_log_message(logger_log_t *log, log_level_t level)
190{
191 fibril_mutex_lock(&log_list_guard);
192 bool result = level <= get_actual_log_level(log);
193 fibril_mutex_unlock(&log_list_guard);
194 return result;
195}
196
197void log_unlock(logger_log_t *log)
198{
199 assert(fibril_mutex_is_locked(&log->guard));
200 fibril_mutex_unlock(&log->guard);
201}
202
203void write_to_log(logger_log_t *log, log_level_t level, const char *message)
204{
205 assert(fibril_mutex_is_locked(&log->guard));
206 assert(log->dest != NULL);
207 fibril_mutex_lock(&log->dest->guard);
208 if (log->dest->logfile == NULL)
209 log->dest->logfile = fopen(log->dest->filename, "a");
210
211 if (log->dest->logfile != NULL) {
212 fprintf(log->dest->logfile, "[%s] %s: %s\n",
213 log->full_name, log_level_str(level),
214 (const char *) message);
215 fflush(log->dest->logfile);
216 }
217
218 fibril_mutex_unlock(&log->dest->guard);
219}
220
221/**
222 * @}
223 */
Note: See TracBrowser for help on using the repository browser.