Changeset 131d9a4 in mainline for uspace/srv/logger/logs.c


Ignore:
Timestamp:
2012-09-07T07:56:01Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
70253688
Parents:
b6933f3
Message:

Logger: destroy logs on client disconnect

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/logger/logs.c

    rb6933f3 r131d9a4  
    128128                        goto leave;
    129129                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                }
    130135        }
    131136
     
    200205}
    201206
     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 */
     214void 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
    202287void write_to_log(logger_log_t *log, log_level_t level, const char *message)
    203288{
     
    218303}
    219304
     305void registered_logs_init(logger_registered_logs_t *logs)
     306{
     307        logs->logs_count = 0;
     308}
     309
     310bool 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
     325void 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
    220334/**
    221335 * @}
Note: See TracChangeset for help on using the changeset viewer.