⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fen-data.c

📁 this is a glib for c language
💻 C
📖 第 1 页 / 共 2 页
字号:
        return 0;    }}voidfdata_sub_add (fdata *f, gpointer sub){    FD_W ("[%s] [data: 0x%p ] [s: 0x%p ] %s\n", __func__, f, sub, FN_NAME(f));    g_assert (g_list_find_custom (f->subs, sub, (GCompareFunc)fdata_sub_find) == NULL);    f->subs = g_list_prepend (f->subs, sub);}voidfdata_sub_remove (fdata *f, gpointer sub){    GList *l;    FD_W ("[%s] [data: 0x%p ] [s: 0x%p ] %s\n", __func__, f, sub, FN_NAME(f));    g_assert (g_list_find_custom (f->subs, sub, (GCompareFunc)fdata_sub_find) != NULL);    l = g_list_find_custom (f->subs, sub, (GCompareFunc)fdata_sub_find);    g_assert (l);    g_assert (sub == l->data);    f->subs = g_list_delete_link (f->subs, l);}/** * Adjust self on failing to Port */voidfdata_adjust_deleted (fdata* f){    node_t* parent;    fdata* pdata;    node_op_t op = {NULL, NULL, pre_del_cb, NULL};    /*     * It's a top node. We move it to missing list.     */    parent = get_parent_node (f);    pdata = get_parent_data (f);    if (!FN_IS_PASSIVE(f) ||      children_num (FN_NODE(f)) > 0 ||      (pdata && !FN_IS_PASSIVE(pdata))) {        if (parent) {            if (pdata == NULL) {                pdata = fdata_new (parent, FALSE);            }            g_assert (pdata);            if (!port_add (&pdata->fobj, &pdata->len, pdata)) {                fdata_adjust_deleted (pdata);            }        } else {            /* f is root */            g_assert (IS_TOPNODE(FN_NODE(f)));            missing_add (f);        }    } else {#ifdef GIO_COMPILATION        pending_remove_node (FN_NODE(f), &op);#else        remove_node (FN_NODE(f), &op);#endif    }}static gbooleanfdata_adjust_changed (fdata *f){    fnode_event_t *ev;    struct stat buf;    node_t* parent;    fdata* pdata;    G_LOCK (fen_lock);    parent = get_parent_node (f);    pdata = get_parent_data (f);    if (!FN_IS_LIVING(f) ||      (children_num (FN_NODE(f)) == 0 &&        FN_IS_PASSIVE(f) &&        pdata && FN_IS_PASSIVE(pdata))) {        f->change_update_id = 0;        G_UNLOCK (fen_lock);        return FALSE;    }    FD_W ("[ %s ] %s\n", __func__, FN_NAME(f));    if (FN_STAT (FN_NAME(f), &buf) != 0) {        FD_W ("LSTAT [%-20s] %s\n", FN_NAME(f), g_strerror (errno));        goto L_delete;    }    f->is_dir = S_ISDIR (buf.st_mode) ? TRUE : FALSE;    if (f->len != buf.st_size) {        /* FD_W ("LEN [%lld:%lld] %s\n", f->len, buf.st_size, FN_NAME(f)); */        f->len = buf.st_size;        ev = fnode_event_new (FILE_MODIFIED, TRUE, f);        if (ev != NULL) {            ev->is_pending = TRUE;            fdata_add_event (f, ev);        }        /* Fdata is still changing, so scalable scan */        f->change_update_id = g_timeout_add (get_scalable_scan_time (f),          (GSourceFunc)fdata_adjust_changed,          (gpointer)f);        G_UNLOCK (fen_lock);        return FALSE;    } else {        f->changed_event_num = 0;        f->fobj.fo_atime = buf.st_atim;        f->fobj.fo_mtime = buf.st_mtim;        f->fobj.fo_ctime = buf.st_ctim;        if (FN_IS_DIR(f)) {            if (FN_IS_MONDIR(f)) {                scan_children (FN_NODE(f));            } else {                scan_known_children (FN_NODE(f));                if ((children_num (FN_NODE(f)) == 0 &&                      FN_IS_PASSIVE(f) &&                      pdata && FN_IS_PASSIVE(pdata))) {                    port_remove (f);                    goto L_exit;                }            }        }        if (!port_add_simple (&f->fobj, f)) {        L_delete:            ev = fnode_event_new (FILE_DELETE, FALSE, f);            if (ev != NULL) {                fdata_add_event (f, ev);            }        }    }L_exit:    f->change_update_id = 0;    G_UNLOCK (fen_lock);    return FALSE;}voidfdata_emit_events_once (fdata *f, int event, gpointer sub){    emit_once_cb (f, _event_converter (event), sub);}voidfdata_emit_events (fdata *f, int event){    emit_cb (f, _event_converter (event));}static gbooleanprocess_events (gpointer udata){    node_op_t op = {NULL, NULL, pre_del_cb, NULL};    fdata* f;    fnode_event_t* ev;    int e;    /* FD_W ("IN <======== %s\n", __func__); */    f = (fdata*)udata;    FD_W ("%s 0x%p id:%-4d %s\n", __func__, f, f->eventq_id, FN_NAME(f));        G_LOCK (fen_lock);    if (!FN_IS_LIVING(f)) {        f->eventq_id = 0;        G_UNLOCK (fen_lock);        return FALSE;    }        if ((ev = (fnode_event_t*)g_queue_pop_head (f->eventq)) != NULL) {        /* Send events to clients. */        e = ev->e;        if (!ev->is_pending) {#ifdef GIO_COMPILATION            if (ev->has_twin) {                fdata_emit_events (f, FILE_ATTRIB);            }#endif            fdata_emit_events (f, ev->e);        }                fnode_event_delete (ev);        ev = NULL;        /* Adjust node state. */        /*         * Node the node has been created, so we can delete create event in         * optimizing. To reduce the statings, we add it to Port on discoving         * it then emit CREATED event. So we don't need to do anything here.         */        switch (e) {        case FILE_MODIFIED:        case MOUNTEDOVER:        case UNMOUNTED:            /* If the event is a changed event, then pending process it */            if (f->change_update_id == 0) {                f->change_update_id = g_timeout_add (get_scalable_scan_time(f),                  (GSourceFunc)fdata_adjust_changed,                  (gpointer)f);                g_assert (f->change_update_id > 0);            }            break;        case FILE_ATTRIB:            g_assert (f->change_update_id == 0);            if (!port_add (&f->fobj, &f->len, f)) {                ev = fnode_event_new (FILE_DELETE, FALSE, f);                if (ev != NULL) {                    fdata_add_event (f, ev);                }            }            break;        case FILE_DELETE: /* Ignored */            break;        default:            g_assert_not_reached ();            break;        }        /* Process one event a time */        G_UNLOCK (fen_lock);         return TRUE;    }    f->eventq_id = 0;    G_UNLOCK (fen_lock);     /* FD_W ("OUT ========> %s\n", __func__); */    return FALSE;}/** * fdata_add_event: * */voidfdata_add_event (fdata *f, fnode_event_t *ev){    node_op_t op = {NULL, NULL, pre_del_cb, NULL};    fnode_event_t *tail;    if (!FN_IS_LIVING(f)) {        fnode_event_delete (ev);        return;    }        FD_W ("%s %d\n", __func__, ev->e);    g_get_current_time (&ev->t);    /*     * If created/deleted events of child node happened, then we use parent     * event queue to handle.     * If child node emits deleted event, it seems no changes for the parent     * node, but the attr is changed. So we may try to cancel processing the     * coming changed events of the parent node.     */    tail = (fnode_event_t*)g_queue_peek_tail (f->eventq);    switch (ev->e) {    case FILE_RENAME_FROM:    case FILE_RENAME_TO:    case FILE_ACCESS:        fnode_event_delete (ev);        g_assert_not_reached ();        return;    case FILE_DELETE:        /* clear changed event number */        f->changed_event_num = 0;        /*         * We will cancel all previous events.         */        if (tail) {            g_queue_pop_tail (f->eventq);            do {                fnode_event_delete (tail);            } while ((tail = (fnode_event_t*)g_queue_pop_tail (f->eventq)) != NULL);        }        /*         * Given a node "f" is deleted, process it ASAP.         */        fdata_emit_events (f, ev->e);        fnode_event_delete (ev);        fdata_adjust_deleted (f);        return;    case FILE_MODIFIED:    case UNMOUNTED:    case MOUNTEDOVER:        /* clear changed event number */        f->changed_event_num ++;    case FILE_ATTRIB:    default:        /*         * If in the time range, we will try optimizing         * (changed+) to (changed)         * (attrchanged changed) to ([changed, attrchanged])         * (event attrchanged) to ([event, attrchanged])         */        if (tail) {            do {                if (tail->e == ev->e) {                    if (g_timeval_lt (&ev->t, &tail->t)) {                        g_queue_peek_tail (f->eventq);                        /* Add the increment */                        g_time_val_add (&ev->t, PAIR_EVENTS_INC_TIMEVAL);                        /* skip the previous event */                        FD_W ("SKIPPED -- %s\n", _event_string (tail->e));                        fnode_event_delete (tail);                    } else {                        break;                    }                } else if (ev->e == FILE_MODIFIED && tail->e == FILE_ATTRIB) {                    ev->has_twin = TRUE;                    fnode_event_delete (tail);                } else if (ev->e == FILE_ATTRIB && f->change_update_id > 0) {                    tail->has_twin = TRUE;                    /* skip the current event */                    fnode_event_delete (ev);                    return;                } else {                    break;                }            } while ((tail = (fnode_event_t*)g_queue_peek_tail (f->eventq)) != NULL);        }    }    /* must add the threshold time */    g_time_val_add (&ev->t, PAIR_EVENTS_TIMEVAL);        g_queue_push_tail (f->eventq, ev);    /* starting process_events */    if (f->eventq_id == 0) {        f->eventq_id = g_timeout_add (PROCESS_EVENTQ_TIME,          process_events,          (gpointer)f);        g_assert (f->eventq_id > 0);    }    FD_W ("%s 0x%p id:%-4d %s\n", __func__, f, f->eventq_id, FN_NAME(f));}gbooleanfdata_class_init (void (*user_emit_cb) (fdata*, int),  void (*user_emit_once_cb) (fdata*, int,  gpointer),  int (*user_event_converter) (int event)){    FD_W ("%s\n", __func__);    if (user_emit_cb == NULL) {        return FALSE;    }    if (user_emit_once_cb == NULL) {        return FALSE;    }    if (user_event_converter == NULL) {        return FALSE;    }    emit_cb = user_emit_cb;    emit_once_cb = user_emit_once_cb;    _event_converter = user_event_converter;        if (!port_class_init (fdata_add_event)) {        FD_W ("port_class_init failed.");        return FALSE;    }    return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -