コード例 #1
0
static inline unsigned char do_cache2(struct cache2 *self)
{
    uint32_t current_serial;
    int change_detected;
    unsigned char c;

    if (pthread_mutex_trylock(&self->lock)) {
        /* We are willing to accept some race in this context */
        return self->evaluate(self);
    }

    change_detected = check_cache(&self->cache_persist)
                   || check_cache(&self->cache_ro);
    current_serial = __system_property_area_serial();
    if (current_serial != self->serial) {
        change_detected = 1;
    }
    if (change_detected) {
        refresh_cache(&self->cache_persist, self->key_persist);
        refresh_cache(&self->cache_ro, self->key_ro);
        self->serial = current_serial;
    }
    c = self->evaluate(self);

    pthread_mutex_unlock(&self->lock);

    return c;
}
コード例 #2
0
LIBLOG_ABI_PRIVATE int __android_log_is_debuggable()
{
    static uint32_t serial;
    static struct cache_char tag_cache;
    static const char key[] = "ro.debuggable";
    int ret;

    if (tag_cache.c) { /* ro property does not change after set */
        ret = tag_cache.c == '1';
    } else if (lock()) {
        struct cache_char temp_cache = { { NULL, -1 }, '\0' };
        refresh_cache(&temp_cache, key);
        ret = temp_cache.c == '1';
    } else {
        int change_detected = check_cache(&tag_cache.cache);
        uint32_t current_serial = __system_property_area_serial();
        if (current_serial != serial) {
            change_detected = 1;
        }
        if (change_detected) {
            refresh_cache(&tag_cache, key);
            serial = current_serial;
        }
        ret = tag_cache.c == '1';

        unlock();
    }

    return ret;
}
コード例 #3
0
char android_log_timestamp()
{
    static struct cache r_time_cache = { NULL, -1, 0 };
    static struct cache p_time_cache = { NULL, -1, 0 };
    char retval;

    if (pthread_mutex_trylock(&lock_timestamp)) {
        /* We are willing to accept some race in this context */
        if (!(retval = p_time_cache.c)) {
            retval = r_time_cache.c;
        }
    } else {
        static uint32_t serial;
        uint32_t current_serial = __system_property_area_serial();
        if (current_serial != serial) {
            refresh_cache(&r_time_cache, "ro.logd.timestamp");
            refresh_cache(&p_time_cache, "persist.logd.timestamp");
            serial = current_serial;
        }
        if (!(retval = p_time_cache.c)) {
            retval = r_time_cache.c;
        }

        pthread_mutex_unlock(&lock_timestamp);
    }

    return tolower(retval ?: 'r');
}
コード例 #4
0
static int __android_log_level(const char *tag, int default_prio)
{
    /* sizeof() is used on this array below */
    static const char log_namespace[] = "persist.log.tag.";
    static const size_t base_offset = 8; /* skip "persist." */
    /* calculate the size of our key temporary buffer */
    const size_t taglen = (tag && *tag) ? strlen(tag) : 0;
    /* sizeof(log_namespace) = strlen(log_namespace) + 1 */
    char key[sizeof(log_namespace) + taglen]; /* may be > PROPERTY_KEY_MAX */
    char *kp;
    size_t i;
    char c = 0;
    /*
     * Single layer cache of four properties. Priorities are:
     *    log.tag.<tag>
     *    persist.log.tag.<tag>
     *    log.tag
     *    persist.log.tag
     * Where the missing tag matches all tags and becomes the
     * system global default. We do not support ro.log.tag* .
     */
    static char last_tag[PROP_NAME_MAX];
    static uint32_t global_serial;
    /* some compilers erroneously see uninitialized use. !not_locked */
    uint32_t current_global_serial = 0;
    static struct cache tag_cache[2];
    static struct cache global_cache[2];
    int change_detected;
    int global_change_detected;
    int not_locked;

    strcpy(key, log_namespace);

    global_change_detected = change_detected = not_locked = lock();

    if (!not_locked) {
        /*
         *  check all known serial numbers to changes.
         */
        for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
            if (check_cache(&tag_cache[i])) {
                change_detected = 1;
            }
        }
        for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
            if (check_cache(&global_cache[i])) {
                global_change_detected = 1;
            }
        }

        current_global_serial = __system_property_area_serial();
        if (current_global_serial != global_serial) {
            change_detected = 1;
            global_change_detected = 1;
        }
    }

    if (taglen) {
        int local_change_detected = change_detected;
        if (!not_locked) {
            if (!last_tag[0]
                    || (last_tag[0] != tag[0])
                    || strncmp(last_tag + 1, tag + 1, sizeof(last_tag) - 1)) {
                /* invalidate log.tag.<tag> cache */
                for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
                    tag_cache[i].pinfo = NULL;
                    tag_cache[i].c = '\0';
                }
                last_tag[0] = '\0';
                local_change_detected = 1;
            }
            if (!last_tag[0]) {
                strncpy(last_tag, tag, sizeof(last_tag));
            }
        }
        strcpy(key + sizeof(log_namespace) - 1, tag);

        kp = key;
        for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
            struct cache *cache = &tag_cache[i];
            struct cache temp_cache;

            if (not_locked) {
                temp_cache.pinfo = NULL;
                temp_cache.c = '\0';
                cache = &temp_cache;
            }
            if (local_change_detected) {
                refresh_cache(cache, kp);
            }

            if (cache->c) {
                c = cache->c;
                break;
            }

            kp = key + base_offset;
        }
    }

    switch (toupper(c)) { /* if invalid, resort to global */
    case 'V':
    case 'D':
    case 'I':
    case 'W':
    case 'E':
    case 'F': /* Not officially supported */
    case 'A':
    case 'S':
    case BOOLEAN_FALSE: /* Not officially supported */
        break;
    default:
        /* clear '.' after log.tag */
        key[sizeof(log_namespace) - 2] = '\0';

        kp = key;
        for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
            struct cache *cache = &global_cache[i];
            struct cache temp_cache;

            if (not_locked) {
                temp_cache = *cache;
                if (temp_cache.pinfo != cache->pinfo) { /* check atomic */
                    temp_cache.pinfo = NULL;
                    temp_cache.c = '\0';
                }
                cache = &temp_cache;
            }
            if (global_change_detected) {
                refresh_cache(cache, kp);
            }

            if (cache->c) {
                c = cache->c;
                break;
            }

            kp = key + base_offset;
        }
        break;
    }

    if (!not_locked) {
        global_serial = current_global_serial;
        unlock();
    }

    switch (toupper(c)) {
    case 'V': return ANDROID_LOG_VERBOSE;
    case 'D': return ANDROID_LOG_DEBUG;
    case 'I': return ANDROID_LOG_INFO;
    case 'W': return ANDROID_LOG_WARN;
    case 'E': return ANDROID_LOG_ERROR;
    case 'F': /* FALLTHRU */ /* Not officially supported */
    case 'A': return ANDROID_LOG_FATAL;
    case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */
    case 'S': return -1; /* ANDROID_LOG_SUPPRESS */
    }
    return default_prio;
}
コード例 #5
0
static int __android_log_level(const char *tag, int flag)
{
    /* sizeof() is used on this array below */
    static const char log_namespace[] = "persist.log.tag.";
    static const size_t base_offset = 8; /* skip "persist." */
    /* calculate the size of our key temporary buffer */
    const size_t taglen = (tag && *tag) ? strlen(tag) : 0;
    /* sizeof(log_namespace) = strlen(log_namespace) + 1 */
    char key[sizeof(log_namespace) + taglen];
    char *kp;
    size_t i;
    char c = 0;
    /*
     * Single layer cache of four properties. Priorities are:
     *    log.tag.<tag>
     *    persist.log.tag.<tag>
     *    log.tag
     *    persist.log.tag
     * Where the missing tag matches all tags and becomes the
     * system global default. We do not support ro.log.tag* .
     */
    static char *last_tag;
    static uint32_t global_serial;
    uint32_t current_global_serial;
    static struct cache tag_cache[2] = {
        { NULL, -1, 0 },
        { NULL, -1, 0 }
    };
    static struct cache global_cache[2] = {
        { NULL, -1, 0 },
        { NULL, -1, 0 }
    };
    sigset_t sigflags;

    strcpy(key, log_namespace);

    lock((flag & ANDROID_LOGGABLE_FLAG_NOT_WITHIN_SIGNAL) ? NULL : &sigflags);

    current_global_serial = __system_property_area_serial();

    if (taglen) {
        uint32_t current_local_serial = current_global_serial;

        if (!last_tag || (last_tag[0] != tag[0]) || strcmp(last_tag + 1, tag + 1)) {
            /* invalidate log.tag.<tag> cache */
            for(i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
                tag_cache[i].pinfo = NULL;
                tag_cache[i].serial = -1;
                tag_cache[i].c = '\0';
            }
            free(last_tag);
            last_tag = NULL;
            current_global_serial = -1;
        }
        if (!last_tag) {
            last_tag = strdup(tag);
        }
        strcpy(key + sizeof(log_namespace) - 1, tag);

        kp = key;
        for(i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
            if (current_local_serial != global_serial) {
                refresh_cache(&tag_cache[i], kp);
            }

            if (tag_cache[i].c) {
                c = tag_cache[i].c;
                break;
            }

            kp = key + base_offset;
        }
    }

    switch (toupper(c)) { /* if invalid, resort to global */
    case 'V':
    case 'D':
    case 'I':
    case 'W':
    case 'E':
    case 'F': /* Not officially supported */
    case 'A':
    case 'S':
        break;
    default:
        /* clear '.' after log.tag */
        key[sizeof(log_namespace) - 2] = '\0';

        kp = key;
        for(i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
            if (current_global_serial != global_serial) {
                refresh_cache(&global_cache[i], kp);
            }

            if (global_cache[i].c) {
                c = global_cache[i].c;
                break;
            }

            kp = key + base_offset;
        }
        break;
    }

    global_serial = current_global_serial;

    unlock((flag & ANDROID_LOGGABLE_FLAG_NOT_WITHIN_SIGNAL) ? NULL : &sigflags);

    switch (toupper(c)) {
    case 'V': return ANDROID_LOG_VERBOSE;
    case 'D': return ANDROID_LOG_DEBUG;
    case 'I': return ANDROID_LOG_INFO;
    case 'W': return ANDROID_LOG_WARN;
    case 'E': return ANDROID_LOG_ERROR;
    case 'F': /* FALLTHRU */ /* Not officially supported */
    case 'A': return ANDROID_LOG_FATAL;
    case 'S': return -1; /* ANDROID_LOG_SUPPRESS */
    }
    return flag & ANDROID_LOGGABLE_FLAG_DEFAULT_MASK;
}