shared_LIBRARIES = contract
-contract_SOURCES = fres_contract.c fres_container.c fres_error.c contract_func.c utils.c
-contract_CLIENT_IDL = fres_contract_idl.idl fres_blocks.idl
+contract_SOURCES = fres_contract.c fres_container.c fres_error.c \
+ contract_func.c utils.c fres_transaction.c
+contract_CLIENT_IDL = fres_contract_idl.idl fres_blocks.idl \
+ fres_transaction_idl.idl
fres_contract_idl_IDLFLAGS = --include=fres_contract_ser.h
fres_blocks_IDLFLAGS = --include=idl_native.h
-include_HEADERS = fres_container.h fres_container_type.h \
- fres_contract_type.h fres_contract_ser.h \
- fres_container_internal.h idl_native.h \
- fres_contract.h fres_error.h
+include_HEADERS = fres_container.h fres_container_type.h \
+ fres_contract_type.h fres_contract_ser.h \
+ fres_container_internal.h idl_native.h \
+ fres_contract.h fres_error.h fres_transaction.h
-include_GEN_HEADERS = fres_contract_idl.h fres_blocks.h
+include_GEN_HEADERS = fres_contract_idl.h fres_blocks.h \
+ fres_transaction_idl.h
SUBDIRS=tests
--- /dev/null
+/**
+ * @file fres_transaction.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Mon Jun 21 16:34:00 2010
+ *
+ * @brief Distributed transaction manipulation
+ */
+
+#include <fres_transaction.h>
+
+/**
+ * Allocates new transaction.
+ *
+ * @return Pointer to the newly allocated transaction or NULL in case
+ * of error.
+ */
+fres_transaction_t*
+fres_transaction_new()
+{
+ fres_transaction_t *t;
+
+ t = malloc(sizeof(*t));
+ if (!t)
+ goto err;
+ memset(t, 0, sizeof(*t));
+ CORBA_sequence_set_release(&t->contracts, CORBA_TRUE);
+ return t;
+err:
+ return NULL;
+}
+
+void
+fres_transaction_destroy(fres_transaction_t *t)
+{
+ if (t) {
+ forb_sequence_free_buf(&t->contracts, fres_contract_ptr_destroy);
+ free(t->name);
+ free(t);
+ }
+}
+
+fres_transaction_t *
+fres_transaction_duplicate(fres_transaction_t *src)
+{
+ fres_transaction_t *dst;
+ int i;
+
+ if (!src)
+ goto err;
+ dst = malloc(sizeof(*dst));
+ /* Copy all static mambers */
+ memcpy(dst, src, sizeof(*dst));
+ /* And now the dynamic ones */
+ if (src->name)
+ dst->name = strdup(src->name);
+ forb_sequence_alloc_buf(&dst->contracts,
+ fres_transaction_num_contracts(src));
+ for (i = 0; i < fres_transaction_num_contracts(src); i++) {
+ struct fres_contract *c;
+ c = fres_transaction_get_contract(src, i);
+ fres_transaction_add_contract(dst, fres_contract_duplicate(c));
+ }
+ return dst;
+err:
+ return NULL;
+}
+
+int
+fres_transaction_add_contract(fres_transaction_t *t,
+ struct fres_contract *c)
+{
+ void *ptr;
+ unsigned num = forb_sequence_length(&t->contracts);
+ ptr = forb_sequence_ensure_allocated(&t->contracts, num+1);
+ if (!ptr)
+ goto err;
+ forb_sequence_elem(&t->contracts, num) = c;
+ forb_sequence_length(&t->contracts)++;
+ return forb_sequence_length(&t->contracts);
+err:
+ return -1;
+}
--- /dev/null
+#ifndef FRES_TRANSACTION_H
+#define FRES_TRANSACTION_H
+
+#include <fres_transaction_idl.h>
+#include <fres_contract.h>
+
+fres_transaction_t*
+fres_transaction_new(void);
+
+void
+fres_transaction_destroy(fres_transaction_t *t);
+
+fres_transaction_t *
+fres_transaction_duplicate(fres_transaction_t *t);
+
+int
+fres_transaction_add_contract(fres_transaction_t *t,
+ struct fres_contract *c);
+
+static inline unsigned
+fres_transaction_num_contracts(fres_transaction_t *t)
+{
+ return forb_sequence_length(&t->contracts);
+}
+
+
+static inline struct fres_contract*
+fres_transaction_get_contract(fres_transaction_t *t, unsigned index)
+{
+ if (index < fres_transaction_num_contracts(t))
+ return forb_sequence_elem(&t->contracts, index);
+ else
+ return NULL;
+}
+
+
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright © 2010 Michal Sojka //
+// //
+// This file is part of FRSH/FORB. //
+// //
+// FRSH/FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FRSH/FORB header files in a file, //
+// instantiating FRSH/FORB generics or templates, or linking other files //
+// with FRSH/FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file fres_transaction_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Definitions of data types and constants for FRSH distributed
+ * transactions.
+ *
+ */
+
+#ifndef _TRANSACTION_IDL
+#define _TRANSACTION_IDL
+
+#include "fres_contract_idl.idl"
+
+module fres {
+ struct transaction_t {
+ string name;
+ contract::ptr_seq contracts;
+ boolean consistent_spare_capacity;
+ };
+};
+
+#endif
--- /dev/null
+#include <fres_transaction.h>
+#include <error.h>
+#include <errno.h>
+#include <wvtest.h>
+
+void cmp(struct fres_contract *c1, struct fres_contract *c2, const char *msg)
+{
+ int ret;
+ if (!WVPASS((ret = strcmp(fres_contract_get_label(c1)->label,
+ fres_contract_get_label(c2)->label)) == 0))
+ error(1, 0, "%s: label cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_resource(c1),
+ fres_contract_get_resource(c2),
+ sizeof(fres_block_resource))) == 0))
+ error(1, 0, "%s: resource cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_basic(c1),
+ fres_contract_get_basic(c2),
+ sizeof(fres_block_basic))) == 0))
+ error(1, 0, "%s: basic cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_timing_reqs(c1),
+ fres_contract_get_timing_reqs(c2),
+ sizeof(fres_block_timing_reqs))) == 0))
+ error(1, 0, "%s: timing_reqs cmp failed %d", msg, ret);
+
+ /*ret = memcmp(fres_contract_get_csects(c1),
+ fres_contract_get_csects(c2),
+ sizeof(fres_block_csects));
+ if (ret) error(1, 0, "%s: critical_sects cmp failed %d", msg, ret);*/
+}
+
+WVTEST_MAIN("transaction manipulation")
+{
+ fres_transaction_t *t1, *t2;
+ struct fres_contract *c;
+
+ WVPASS(t1 = fres_transaction_new());
+ WVPASS(fres_transaction_num_contracts(t1) == 0);
+ WVFAIL(fres_transaction_get_contract(t1, 0));
+ WVPASS(c = fres_contract_new());
+ WVPASS(fres_transaction_add_contract(t1, c) > 0);
+ WVPASS(fres_transaction_num_contracts(t1) == 1);
+ WVPASS(fres_transaction_get_contract(t1, 0) == c);
+
+ WVPASS(t2 = fres_transaction_duplicate(t1));
+ WVPASS(fres_transaction_num_contracts(t2) == 1);
+ WVPASS(fres_transaction_get_contract(t2, 0) != NULL);
+ WVPASS(fres_transaction_get_contract(t2, 0) != c);
+
+ fres_transaction_destroy(t1);
+}