Changeset 5e718d9 in mainline for uspace/lib/bithenge/sequence.c


Ignore:
Timestamp:
2012-08-21T10:04:16Z (12 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
67edca6
Parents:
0da6c04 (diff), 6a97f2e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge with upstream (lp:~wtachi/helenos/bithenge)

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/bithenge/sequence.c

    r0da6c04 r5e718d9  
    418418        struct_node_t *node = node_as_struct(base);
    419419
    420         /* We didn't inc_ref for the scope in struct_transform_make_node, so
    421          * make sure it doesn't try to dec_ref. */
    422         seq_node_scope(struct_as_seq(node))->current_node = NULL;
    423         seq_node_destroy(struct_as_seq(node));
     420        /* Treat the scope carefully because of the circular reference. In
     421         * struct_transform_make_node, things are set up so node owns a
     422         * reference to the scope, but scope doesn't own a reference to node,
     423         * so node's reference count is too low. */
     424        bithenge_scope_t *scope = seq_node_scope(struct_as_seq(node));
     425        if (scope->refs == 1) {
     426                /* Mostly normal destroy, but we didn't inc_ref(node) for the
     427                 * scope in struct_transform_make_node, so make sure it doesn't
     428                 * try to dec_ref. */
     429                scope->current_node = NULL;
     430                seq_node_destroy(struct_as_seq(node));
     431        } else if (scope->refs > 1) {
     432                /* The scope is still needed, but node isn't otherwise needed.
     433                 * Switch things around so scope owns a reference to node, but
     434                 * not vice versa, and scope's reference count is too low. */
     435                bithenge_node_inc_ref(base);
     436                bithenge_scope_dec_ref(scope);
     437                return;
     438        } else {
     439                /* This happens after the previous case, when scope is no
     440                 * longer used and is being destroyed. Since scope is already
     441                 * being destroyed, set it to NULL here so we don't try to
     442                 * destroy it twice. */
     443                struct_as_seq(node)->scope = NULL;
     444                seq_node_destroy(struct_as_seq(node));
     445        }
    424446
    425447        bithenge_transform_dec_ref(struct_as_transform(node->transform));
     
    466488                return rc;
    467489        }
     490
     491        rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, inner,
     492            blob, self->num_subtransforms, false);
     493        if (rc != EOK) {
     494                bithenge_scope_dec_ref(inner);
     495                free(node);
     496                return rc;
     497        }
     498
     499        bithenge_transform_inc_ref(struct_as_transform(self));
     500        node->transform = self;
     501        node->prefix = prefix;
     502
    468503        /* We should inc_ref(node) here, but that would make a cycle. Instead,
    469504         * we leave it 1 too low, so that when the only remaining use of node
     
    471506         * struct_node_destroy. */
    472507        bithenge_scope_set_current_node(inner, struct_as_node(node));
    473 
    474         rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, inner,
    475             blob, self->num_subtransforms, false);
    476508        bithenge_scope_dec_ref(inner);
    477         if (rc != EOK) {
    478                 free(node);
    479                 return rc;
    480         }
    481 
    482         bithenge_transform_inc_ref(struct_as_transform(self));
    483         node->transform = self;
    484         node->prefix = prefix;
     509
    485510        *out = struct_as_node(node);
    486511
     
    524549                return rc;
    525550
    526         rc = seq_node_field_offset(node_as_seq(*out_node), out_size,
    527             self->num_subtransforms);
    528         if (rc != EOK) {
    529                 bithenge_node_dec_ref(*out_node);
    530                 return rc;
     551        if (out_size) {
     552                rc = seq_node_field_offset(node_as_seq(*out_node), out_size,
     553                    self->num_subtransforms);
     554                if (rc != EOK) {
     555                        bithenge_node_dec_ref(*out_node);
     556                        return rc;
     557                }
    531558        }
    532559
     
    595622/***************** bithenge_repeat_transform                 *****************/
    596623
     624/* TODO: ignore errors */
     625
    597626typedef struct {
    598627        bithenge_transform_t base;
     
    793822                return rc;
    794823
    795         bithenge_int_t count = node_as_repeat(*out_node)->count;
    796         if (count != -1) {
    797                 rc = seq_node_field_offset(node_as_seq(*out_node), out_size, count);
    798                 if (rc != EOK) {
    799                         bithenge_node_dec_ref(*out_node);
    800                         return rc;
    801                 }
    802         } else {
    803                 *out_size = 0;
    804                 for (count = 1; ; count++) {
    805                         aoff64_t size;
     824        if (out_size) {
     825                bithenge_int_t count = node_as_repeat(*out_node)->count;
     826                if (count != -1) {
    806827                        rc = seq_node_field_offset(node_as_seq(*out_node),
    807                             &size, count);
    808                         if (rc != EOK)
    809                                 break;
    810                         *out_size = size;
     828                            out_size, count);
     829                        if (rc != EOK) {
     830                                bithenge_node_dec_ref(*out_node);
     831                                return rc;
     832                        }
     833                } else {
     834                        *out_size = 0;
     835                        for (count = 1; ; count++) {
     836                                aoff64_t size;
     837                                rc = seq_node_field_offset(
     838                                    node_as_seq(*out_node), &size, count);
     839                                if (rc == EINVAL || rc == ENOENT)
     840                                        break;
     841                                if (rc != EOK) {
     842                                        bithenge_node_dec_ref(*out_node);
     843                                        return rc;
     844                                }
     845                                *out_size = size;
     846                        }
    811847                }
    812848        }
     
    886922typedef struct {
    887923        seq_node_t base;
    888         bool prefix;
    889924        bithenge_expression_t *expr;
    890925        bithenge_transform_t *xform;
     
    9661001        }
    9671002
    968         if (!self->prefix) {
    969                 bool complete;
    970                 rc = seq_node_complete(do_while_as_seq(self), &complete);
    971                 if (rc != EOK)
    972                         return rc;
    973                 if (!complete)
    974                         return EINVAL;
    975         }
    976 
    9771003        return rc;
    9781004}
     
    10061032
    10071033static int do_while_transform_make_node(do_while_transform_t *self,
    1008     bithenge_node_t **out, bithenge_scope_t *scope, bithenge_blob_t *blob,
    1009     bool prefix)
     1034    bithenge_node_t **out, bithenge_scope_t *scope, bithenge_blob_t *blob)
    10101035{
    10111036        do_while_node_t *node = malloc(sizeof(*node));
     
    10311056        bithenge_expression_inc_ref(self->expr);
    10321057        node->expr = self->expr;
    1033         node->prefix = prefix;
    10341058        node->count = -1;
    10351059        *out = do_while_as_node(node);
    10361060        return EOK;
    1037 }
    1038 
    1039 static int do_while_transform_apply(bithenge_transform_t *base,
    1040     bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
    1041 {
    1042         do_while_transform_t *self = transform_as_do_while(base);
    1043         if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
    1044                 return EINVAL;
    1045         return do_while_transform_make_node(self, out, scope,
    1046             bithenge_node_as_blob(in), false);
    10471061}
    10481062
     
    10601074{
    10611075        do_while_transform_t *self = transform_as_do_while(base);
    1062         int rc = do_while_transform_make_node(self, out_node, scope, blob,
    1063             true);
     1076        int rc = do_while_transform_make_node(self, out_node, scope, blob);
    10641077        if (rc != EOK)
    10651078                return rc;
    10661079
    1067         rc = bithenge_node_for_each(*out_node, for_each_noop, NULL);
    1068         if (rc != EOK) {
    1069                 bithenge_node_dec_ref(*out_node);
    1070                 return rc;
    1071         }
    1072 
    1073         rc = seq_node_field_offset(node_as_seq(*out_node), out_size,
    1074             node_as_do_while(*out_node)->count);
    1075         if (rc != EOK) {
    1076                 bithenge_node_dec_ref(*out_node);
    1077                 return rc;
     1080        if (out_size) {
     1081                rc = bithenge_node_for_each(*out_node, for_each_noop, NULL);
     1082                if (rc != EOK) {
     1083                        bithenge_node_dec_ref(*out_node);
     1084                        return rc;
     1085                }
     1086
     1087                rc = seq_node_field_offset(node_as_seq(*out_node), out_size,
     1088                    node_as_do_while(*out_node)->count);
     1089                if (rc != EOK) {
     1090                        bithenge_node_dec_ref(*out_node);
     1091                        return rc;
     1092                }
    10781093        }
    10791094
     
    10901105
    10911106static const bithenge_transform_ops_t do_while_transform_ops = {
    1092         .apply = do_while_transform_apply,
    10931107        .prefix_apply = do_while_transform_prefix_apply,
    10941108        .destroy = do_while_transform_destroy,
Note: See TracChangeset for help on using the changeset viewer.