Changeset 131d9a4 in mainline
- Timestamp:
- 2012-09-07T07:56:01Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 70253688
- Parents:
- b6933f3
- Location:
- uspace/srv/logger
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/logger/initlvl.c
rb6933f3 r131d9a4 67 67 68 68 log->logged_level = level; 69 log->ref_counter++; 69 70 70 71 log_unlock(log); -
uspace/srv/logger/logger.h
rb6933f3 r131d9a4 58 58 link_t link; 59 59 60 size_t ref_counter; 61 60 62 fibril_mutex_t guard; 61 63 … … 67 69 }; 68 70 71 #define MAX_REFERENCED_LOGS_PER_CLIENT 100 72 73 typedef struct { 74 size_t logs_count; 75 logger_log_t *logs[MAX_REFERENCED_LOGS_PER_CLIENT]; 76 } logger_registered_logs_t; 77 69 78 logger_log_t *find_log_by_name_and_lock(const char *name); 70 79 logger_log_t *find_or_create_log_and_lock(const char *, sysarg_t); … … 73 82 void log_unlock(logger_log_t *); 74 83 void write_to_log(logger_log_t *, log_level_t, const char *); 84 void log_release(logger_log_t *); 85 86 void registered_logs_init(logger_registered_logs_t *); 87 bool register_log(logger_registered_logs_t *, logger_log_t *); 88 void unregister_logs(logger_registered_logs_t *); 75 89 76 90 log_level_t get_default_logging_level(void); -
uspace/srv/logger/logs.c
rb6933f3 r131d9a4 128 128 goto leave; 129 129 list_append(&result->link, &log_list); 130 if (result->parent != NULL) { 131 fibril_mutex_lock(&result->parent->guard); 132 result->parent->ref_counter++; 133 fibril_mutex_unlock(&result->parent->guard); 134 } 130 135 } 131 136 … … 200 205 } 201 206 207 /** Decreases reference counter on the log and destory the log if 208 * necessary. 209 * 210 * Precondition: log is locked. 211 * 212 * @param log Log to release from using by the caller. 213 */ 214 void log_release(logger_log_t *log) 215 { 216 assert(fibril_mutex_is_locked(&log->guard)); 217 assert(log->ref_counter > 0); 218 219 /* We are definitely not the last ones. */ 220 if (log->ref_counter > 1) { 221 log->ref_counter--; 222 fibril_mutex_unlock(&log->guard); 223 return; 224 } 225 226 /* 227 * To prevent deadlock, we need to get the list lock first. 228 * Deadlock scenario: 229 * Us: LOCKED(log), want to LOCK(list) 230 * Someone else calls find_log_by_name_and_lock(log->fullname) -> 231 * LOCKED(list), wants to LOCK(log) 232 */ 233 fibril_mutex_unlock(&log->guard); 234 235 /* Ensuring correct locking order. */ 236 fibril_mutex_lock(&log_list_guard); 237 /* 238 * The reference must be still valid because we have not decreased 239 * the reference counter. 240 */ 241 fibril_mutex_lock(&log->guard); 242 assert(log->ref_counter > 0); 243 log->ref_counter--; 244 245 if (log->ref_counter > 0) { 246 /* 247 * Meanwhile, someone else increased the ref counter. 248 * No big deal, we just return immediatelly. 249 */ 250 fibril_mutex_unlock(&log->guard); 251 fibril_mutex_unlock(&log_list_guard); 252 return; 253 } 254 255 /* 256 * Here we are on a destroy path. We need to 257 * - remove ourselves from the list 258 * - decrease reference of the parent (if not top-level log) 259 * - we must do that after we relaase list lock to prevent 260 * deadlock with ourselves 261 * - destroy dest (if top-level log) 262 */ 263 assert(log->ref_counter == 0); 264 265 list_remove(&log->link); 266 fibril_mutex_unlock(&log_list_guard); 267 fibril_mutex_unlock(&log->guard); 268 269 if (log->parent == NULL) { 270 fclose(log->dest->logfile); 271 free(log->dest->filename); 272 free(log->dest); 273 } else { 274 fibril_mutex_lock(&log->parent->guard); 275 log_release(log->parent); 276 } 277 278 printf("Destroying log %s.\n", log->full_name); 279 280 free(log->name); 281 free(log->full_name); 282 283 free(log); 284 } 285 286 202 287 void write_to_log(logger_log_t *log, log_level_t level, const char *message) 203 288 { … … 218 303 } 219 304 305 void registered_logs_init(logger_registered_logs_t *logs) 306 { 307 logs->logs_count = 0; 308 } 309 310 bool register_log(logger_registered_logs_t *logs, logger_log_t *new_log) 311 { 312 if (logs->logs_count >= MAX_REFERENCED_LOGS_PER_CLIENT) { 313 return false; 314 } 315 316 assert(fibril_mutex_is_locked(&new_log->guard)); 317 new_log->ref_counter++; 318 319 logs->logs[logs->logs_count] = new_log; 320 logs->logs_count++; 321 322 return true; 323 } 324 325 void unregister_logs(logger_registered_logs_t *logs) 326 { 327 for (size_t i = 0; i < logs->logs_count; i++) { 328 logger_log_t *log = logs->logs[i]; 329 fibril_mutex_lock(&log->guard); 330 log_release(log); 331 } 332 } 333 220 334 /** 221 335 * @} -
uspace/srv/logger/writer.c
rb6933f3 r131d9a4 100 100 printf(NAME "/writer: new client.\n"); 101 101 102 logger_registered_logs_t registered_logs; 103 registered_logs_init(®istered_logs); 104 102 105 while (true) { 103 106 ipc_call_t call; … … 112 115 if (log == NULL) { 113 116 async_answer_0(callid, ENOMEM); 117 break; 118 } 119 if (!register_log(®istered_logs, log)) { 120 log_unlock(log); 121 async_answer_0(callid, ELIMIT); 114 122 break; 115 123 } … … 130 138 } 131 139 132 // FIXME: destroy created logs140 unregister_logs(®istered_logs); 133 141 } 134 142
Note:
See TracChangeset
for help on using the changeset viewer.