summaryrefslogtreecommitdiffstats
path: root/src/H5FPserver.c
diff options
context:
space:
mode:
authorBill Wendling <wendling@ncsa.uiuc.edu>2003-02-03 20:41:53 (GMT)
committerBill Wendling <wendling@ncsa.uiuc.edu>2003-02-03 20:41:53 (GMT)
commit9b9c71ffb6dc4e4b789cabf75a8be096f6ea53b3 (patch)
treef29cd90a8a8da471da04f44491459f9f115fc503 /src/H5FPserver.c
parente91291e4588711a1f9c90137c85b77e5cb34dd04 (diff)
downloadhdf5-9b9c71ffb6dc4e4b789cabf75a8be096f6ea53b3.zip
hdf5-9b9c71ffb6dc4e4b789cabf75a8be096f6ea53b3.tar.gz
hdf5-9b9c71ffb6dc4e4b789cabf75a8be096f6ea53b3.tar.bz2
[svn-r6371] Purpose:
Update Description: Changes: - Added support for the server dumping metadata writes to a client. - Some of the code wasn't handling allocated buffers correctly (freeing twice). - Modified server so that it handles metadata only. Platforms tested: Linux
Diffstat (limited to 'src/H5FPserver.c')
-rw-r--r--src/H5FPserver.c489
1 files changed, 299 insertions, 190 deletions
diff --git a/src/H5FPserver.c b/src/H5FPserver.c
index e073feb..6f44933 100644
--- a/src/H5FPserver.c
+++ b/src/H5FPserver.c
@@ -53,6 +53,7 @@ typedef struct {
} H5FP_object_lock;
typedef struct {
+ H5FD_mem_t mem_type; /* type of memory updated, if req'd */
H5AC_subid_t type_id; /* id of the type of this metadata */
H5FP_obj_t obj_type; /* type of object modified */
haddr_t addr; /* address of the metadata */
@@ -64,11 +65,18 @@ typedef struct {
unsigned file_id; /* the file id the SAP keeps per file */
char *filename; /* the filename - of dubious use */
int closing; /* we're closing the file - no more changes */
+ unsigned num_mods; /* number of mdata writes outstanding */
H5TB_TREE *mod_tree; /* a tree of metadata updates done */
H5TB_TREE *locks; /* a tree of locks on objects in the file */
} H5FP_file_info;
-static H5TB_TREE *fs_tree;
+/*
+ * This marks the point at which we want to dump all of the metadata
+ * write to a process so that that process can write them to the file.
+ */
+#define H5FP_MDATA_CACHE_HIGHWATER_MARK 1024
+
+static H5TB_TREE *file_info_tree;
/* local functions */
static herr_t H5FP_sap_receive(H5FP_request *req, int source, int tag, char **buf);
@@ -77,14 +85,18 @@ static herr_t H5FP_sap_receive(H5FP_request *req, int source, int tag, char **bu
static unsigned H5FP_gen_sap_file_id(void);
/* local functions for handling object locks */
-static int H5FP_object_lock_cmp(H5FP_object_lock *o1, H5FP_object_lock *o2, int cmparg);
+static int H5FP_object_lock_cmp(H5FP_object_lock *o1,
+ H5FP_object_lock *o2,
+ int cmparg);
static H5FP_object_lock *H5FP_new_object_lock(const unsigned char *oid,
unsigned rank,
H5FP_obj_t obj_type,
H5FP_lock_t rw_lock);
static herr_t H5FP_free_object_lock(H5FP_object_lock *ol);
-static H5FP_object_lock *H5FP_find_object_lock(H5FP_file_info *fs, unsigned char *oid);
-static herr_t H5FP_remove_object_lock_from_list(H5FP_file_info *fs, H5FP_object_lock *ol);
+static H5FP_object_lock *H5FP_find_object_lock(H5FP_file_info *info,
+ unsigned char *oid);
+static herr_t H5FP_remove_object_lock_from_list(H5FP_file_info *info,
+ H5FP_object_lock *ol);
/* local file information handling functions */
static herr_t H5FP_add_new_file_info_to_list(unsigned file_id, char *filename);
@@ -92,21 +104,26 @@ static int H5FP_file_info_cmp(H5FP_file_info *k1, H5FP_file_info *k2, int cmparg
static H5FP_file_info *H5FP_new_file_info_node(unsigned file_id, char *filename);
static H5FP_file_info *H5FP_find_file_info(unsigned file_id);
static herr_t H5FP_remove_file_id_from_list(unsigned file_id);
-static herr_t H5FP_free_file_info_node(H5FP_file_info *fs);
+static herr_t H5FP_free_file_info_node(H5FP_file_info *info);
/* local file modification structure handling functions */
static H5FP_mdata_mod *H5FP_new_file_mod_node(unsigned rank,
+ H5FD_mem_t mem_type,
H5AC_subid_t type_id,
haddr_t addr,
- int md_size,
+ unsigned md_size,
char *metadata);
-static herr_t H5FP_free_mod_node(H5FP_mdata_mod *fs);
+static herr_t H5FP_free_mod_node(H5FP_mdata_mod *info);
/* local request handling functions */
-static herr_t H5FP_sap_handle_open_request(H5FP_request req, char *mdata, int md_size);
+static herr_t H5FP_sap_handle_open_request(H5FP_request req,
+ char *mdata,
+ unsigned md_size);
static herr_t H5FP_sap_handle_lock_request(H5FP_request req);
static herr_t H5FP_sap_handle_release_lock_request(H5FP_request req);
-static herr_t H5FP_sap_handle_write_request(H5FP_request req, char *mdata, int md_size);
+static herr_t H5FP_sap_handle_write_request(H5FP_request req,
+ char *mdata,
+ unsigned md_size);
static herr_t H5FP_sap_handle_read_request(H5FP_request req);
static herr_t H5FP_sap_handle_close_request(H5FP_request req);
@@ -136,8 +153,8 @@ H5FP_sap_receive_loop(void)
FUNC_ENTER_NOAPI(H5FP_sap_receive_loop, FAIL);
/* Create the file structure tree. */
- if ((fs_tree = H5TB_dmake((H5TB_cmp_t)H5FP_file_info_cmp,
- sizeof(H5FP_file_info), FALSE)) == NULL)
+ if ((file_info_tree = H5TB_dmake((H5TB_cmp_t)H5FP_file_info_cmp,
+ sizeof(H5FP_file_info), FALSE)) == NULL)
HGOTO_ERROR(H5E_FPHDF5, H5E_CANTMAKETREE, FAIL, "cannot make TBBT tree");
for (;;) {
@@ -178,6 +195,9 @@ H5FP_sap_receive_loop(void)
HGOTO_ERROR(H5E_FPHDF5, H5E_ARGS, FAIL, "invalid request type");
}
+ /*
+ * If the above calls didn't succeed, free the buffer
+ */
if (hrc != SUCCEED)
HDfree(buf);
}
@@ -191,8 +211,9 @@ done:
* Purpose: Receive a message from SOURCE with the given TAG. The REQ
* object passed in as a pointer is filled by the MPI_Recv
* function.
- * Return: Pointer to string passed in, if one was sent. As well as
- * the SAP_request object.
+ * Return: Success: Pointer to string passed in, if one was sent.
+ * As well as the SAP_request object.
+ * Failure: FAIL
* Programmer: Bill Wendling, 17. September, 2002
* Modifications:
*/
@@ -211,23 +232,9 @@ H5FP_sap_receive(H5FP_request *req, int source, int tag, char **buf)
H5FP_SAP_COMM, &status)) != MPI_SUCCESS)
HMPI_GOTO_ERROR(FAIL, "MPI_Recv failed", mrc);
- if (buf && req->md_size) {
- /*
- * There is metadata associated with this request. Get it as a
- * string (requires another read).
- */
- if ((*buf = (char *)HDmalloc((size_t)req->md_size + 1)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "out of memory");
-
- HDmemset(*buf, 0, (size_t)req->md_size + 1);
-
- if ((mrc = MPI_Recv(*buf, req->md_size, MPI_BYTE, (int)req->proc_rank,
- H5FP_TAG_METADATA, H5FP_SAP_COMM, &status)) != MPI_SUCCESS) {
- HDfree(*buf);
- *buf = NULL;
- HMPI_GOTO_ERROR(FAIL, "MPI_Recv failed", mrc);
- }
- }
+ if (buf && req->md_size)
+ if (H5FP_read_metadata(buf, (int)req->md_size, (int)req->proc_rank) == FAIL)
+ HGOTO_ERROR(H5E_FPHDF5, H5E_CANTRECV, FAIL, "can't read metadata from process");
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -240,9 +247,10 @@ done:
* Programmer: Bill Wendling, 09. September 2002
* Modifications:
*/
-static int H5FP_object_lock_cmp(H5FP_object_lock *o1,
- H5FP_object_lock *o2,
- int UNUSED cmparg)
+static int
+H5FP_object_lock_cmp(H5FP_object_lock *o1,
+ H5FP_object_lock *o2,
+ int UNUSED cmparg)
{
FUNC_ENTER_NOINIT(H5FP_object_lock_cmp);
assert(o1);
@@ -304,27 +312,28 @@ H5FP_free_object_lock(H5FP_object_lock *ol)
/*
* Function: H5FP_find_object_lock
* Purpose: Find the object lock for the given OID if there is one.
- * Return: Pointer to the object or NULL.
+ * Return: Success: Pointer to the object
+ * Failure: NULL
* Programmer: Bill Wendling, 09. September 2002
* Modifications:
*/
static H5FP_object_lock *
-H5FP_find_object_lock(H5FP_file_info *fs, unsigned char *oid)
+H5FP_find_object_lock(H5FP_file_info *info, unsigned char *oid)
{
H5FP_object_lock *ret_value = NULL;
FUNC_ENTER_NOINIT(H5FP_find_object_lock);
- assert(fs);
+ assert(info);
assert(oid);
- if (fs->locks && fs->locks->root) {
+ if (info->locks && info->locks->root) {
H5TB_NODE *node;
H5FP_object_lock ol;
H5FP_COPY_OID(ol.oid, oid); /* This is the key field for the TBBT */
- if ((node = H5TB_dfind(fs->locks, (void *)&ol, NULL)) == NULL)
+ if ((node = H5TB_dfind(info->locks, (void *)&ol, NULL)) == NULL)
HGOTO_ERROR(H5E_FPHDF5, H5E_NOTFOUND, NULL, "lock not found");
ret_value = (H5FP_object_lock *)node->data;
@@ -344,7 +353,7 @@ done:
* Modifications:
*/
static herr_t
-H5FP_remove_object_lock_from_list(H5FP_file_info *fs,
+H5FP_remove_object_lock_from_list(H5FP_file_info *info,
H5FP_object_lock *ol)
{
H5TB_NODE *node;
@@ -352,8 +361,8 @@ H5FP_remove_object_lock_from_list(H5FP_file_info *fs,
FUNC_ENTER_NOINIT(H5FP_remove_object_lock_from_list);
- if ((node = H5TB_dfind(fs->locks, (void *)ol, NULL)) != NULL) {
- H5FP_free_object_lock(H5TB_rem(&fs->locks->root, node, NULL));
+ if ((node = H5TB_dfind(info->locks, (void *)ol, NULL)) != NULL) {
+ H5FP_free_object_lock(H5TB_rem(&info->locks->root, node, NULL));
ret_value = SUCCEED;
}
@@ -382,19 +391,18 @@ H5FP_file_mod_cmp(H5FP_mdata_mod *k1,
* Function: H5FP_free_mod_node
* Purpose: Helper function to free up an SAP_FILE_MOD node and all
* of the malloced space it has.
- * Return: Success: SUCCEED
- * Failure: Doesn't fail
+ * Return: SUCCEED (doesn't fail)
* Programmer: Bill Wendling, 31. July, 2002
* Modifications:
*/
static herr_t
-H5FP_free_mod_node(H5FP_mdata_mod *fs)
+H5FP_free_mod_node(H5FP_mdata_mod *info)
{
FUNC_ENTER_NOINIT(H5FP_free_mod_node);
- if (fs) {
- HDfree(fs->metadata);
- HDfree(fs);
+ if (info) {
+ HDfree(info->metadata);
+ HDfree(info);
}
FUNC_LEAVE_NOAPI(SUCCEED);
@@ -405,24 +413,24 @@ H5FP_free_mod_node(H5FP_mdata_mod *fs)
* Purpose: Create a new sap_file_mod node and initialize it. This
* object now has responsibility for freeing the metadata
* information.
- * Return: Success: Pointer to new sap_file_mod structure.
- * Failure: NULL
+ * Return: Success: Pointer to new sap_file_mod structure.
+ * Failure: NULL
* Programmer: Bill Wendling, 02. August, 2002
* Modifications:
*/
static H5FP_mdata_mod *
-H5FP_new_file_mod_node(unsigned UNUSED rank, H5AC_subid_t type_id,
- haddr_t addr, int md_size, char *metadata)
+H5FP_new_file_mod_node(unsigned UNUSED rank, H5FD_mem_t mem_type,
+ H5AC_subid_t type_id, haddr_t addr, unsigned md_size,
+ char *metadata)
{
H5FP_mdata_mod *ret_value = NULL;
FUNC_ENTER_NOINIT(H5FP_new_file_mod_node);
- ret_value = (H5FP_mdata_mod *)HDmalloc(sizeof(H5FP_mdata_mod));
-
- if (!ret_value)
+ if ((ret_value = (H5FP_mdata_mod *)HDmalloc(sizeof(H5FP_mdata_mod))) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "out of memory");
+ ret_value->mem_type = mem_type;
ret_value->addr = addr;
ret_value->type_id = type_id;
ret_value->md_size = md_size;
@@ -444,9 +452,9 @@ done:
* Modifications:
*/
static herr_t
-H5FP_add_file_mod_to_list(H5FP_file_info *fs, H5AC_subid_t type_id,
- haddr_t addr, unsigned rank, int md_size,
- char *metadata)
+H5FP_add_file_mod_to_list(H5FP_file_info *info, H5FD_mem_t mem_type,
+ H5AC_subid_t type_id, haddr_t addr, unsigned rank,
+ unsigned md_size, char *metadata)
{
H5FP_mdata_mod *fm, mod;
H5TB_NODE *node;
@@ -454,11 +462,11 @@ H5FP_add_file_mod_to_list(H5FP_file_info *fs, H5AC_subid_t type_id,
FUNC_ENTER_NOINIT(H5FP_add_file_mod_to_list);
- assert(fs);
+ assert(info);
mod.addr = addr; /* This is the key field for the TBBT */
- if ((node = H5TB_dfind(fs->mod_tree, (void *)&mod, NULL)) != NULL) {
+ if ((node = H5TB_dfind(info->mod_tree, (void *)&mod, NULL)) != NULL) {
/*
* The metadata is in the cache already. All we have to do is
* replace what's there. The addr and type should be the same.
@@ -469,9 +477,9 @@ H5FP_add_file_mod_to_list(H5FP_file_info *fs, H5AC_subid_t type_id,
fm->metadata = metadata;
fm->md_size = md_size;
ret_value = SUCCEED;
- } else if ((fm = H5FP_new_file_mod_node(rank, type_id, addr,
+ } else if ((fm = H5FP_new_file_mod_node(rank, mem_type, type_id, addr,
md_size, metadata)) != NULL) {
- if (!H5TB_dins(fs->mod_tree, (void *)fm, NULL))
+ if (!H5TB_dins(info->mod_tree, (void *)fm, NULL))
HGOTO_ERROR(H5E_FPHDF5, H5E_CANTINSERT, FAIL,
"can't insert modification into tree");
@@ -483,52 +491,23 @@ done:
}
/*
- * Function: H5FP_remove_mod_from_list
- * Purpose: Remove a modification from the list of modifications on
- * this file.
- * Return: Success: SUCCEED
- * Failure: FAIL
- * Programmer: Bill Wendling, 31. July, 2002
- * Modifications:
- */
-static herr_t
-H5FP_remove_mod_from_list(H5FP_file_info *fs, H5FP_mdata_mod *mod)
-{
- H5TB_NODE *node;
- herr_t ret_value = FAIL;
-
- FUNC_ENTER_NOINIT(H5FP_remove_mod_from_list);
-
- if ((node = H5TB_dfind(fs->mod_tree, (void *)mod, NULL)) != NULL) {
- H5FP_free_mod_node(H5TB_rem(&fs->mod_tree->root, node, NULL));
- ret_value = SUCCEED;
- }
-
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-/*
* Function: H5FP_free_file_info_node
* Purpose: Helper function to free up an SAP_FILE_STRUCT node and all
* of the malloced space it has.
- *
- * Note: It is an error to call this function before all
- * modifications have been synced with all processes in the
- * H5FP_SAP_COMM.
* Return: SUCCEED (never fails)
* Programmer: Bill Wendling, 31. July, 2002
* Modifications:
*/
static herr_t
-H5FP_free_file_info_node(H5FP_file_info *fs)
+H5FP_free_file_info_node(H5FP_file_info *info)
{
FUNC_ENTER_NOINIT(H5FP_free_file_info_node);
- if (fs) {
- H5TB_dfree(fs->mod_tree, (void (*)(void*))H5FP_free_mod_node, NULL);
- H5TB_dfree(fs->locks, (void (*)(void*))H5FP_free_object_lock, NULL);
- HDfree(fs->filename);
- HDfree(fs);
+ if (info) {
+ H5TB_dfree(info->mod_tree, (void (*)(void*))H5FP_free_mod_node, NULL);
+ H5TB_dfree(info->locks, (void (*)(void*))H5FP_free_object_lock, NULL);
+ HDfree(info->filename);
+ HDfree(info);
}
FUNC_LEAVE_NOAPI(SUCCEED);
@@ -571,6 +550,7 @@ H5FP_new_file_info_node(unsigned file_id, char *filename)
ret_value->file_id = file_id;
ret_value->filename = filename;
ret_value->closing = FALSE;
+ ret_value->num_mods = 0;
if ((ret_value->mod_tree = H5TB_dmake((H5TB_cmp_t)H5FP_file_mod_cmp,
sizeof(H5FP_mdata_mod), FALSE)) == NULL) {
@@ -605,12 +585,12 @@ H5FP_find_file_info(unsigned file_id)
FUNC_ENTER_NOINIT(H5FP_find_file_info);
- if (fs_tree && fs_tree->root) {
+ if (file_info_tree && file_info_tree->root) {
H5FP_file_info s;
s.file_id = file_id; /* This is the key field for the TBBT */
- if ((node = H5TB_dfind(fs_tree, (void *)&s, NULL)) != NULL)
+ if ((node = H5TB_dfind(file_info_tree, (void *)&s, NULL)) != NULL)
ret_value = (H5FP_file_info *)node->data;
}
@@ -628,15 +608,17 @@ H5FP_find_file_info(unsigned file_id)
static herr_t
H5FP_add_new_file_info_to_list(unsigned file_id, char *filename)
{
- H5FP_file_info *fs;
+ H5FP_file_info *info;
herr_t ret_value = FAIL;
FUNC_ENTER_NOINIT(H5FP_add_new_file_info_to_list);
- if ((fs = H5FP_new_file_info_node(file_id, filename)) != NULL) {
- if (!H5TB_dins(fs_tree, (void *)fs, NULL))
+ if ((info = H5FP_new_file_info_node(file_id, filename)) != NULL) {
+ if (!H5TB_dins(file_info_tree, (void *)info, NULL)) {
+ H5FP_free_file_info_node(info);
HGOTO_ERROR(H5E_FPHDF5, H5E_CANTINSERT, FAIL,
"can't insert file structure into tree");
+ }
ret_value = SUCCEED;
}
@@ -669,8 +651,8 @@ H5FP_remove_file_id_from_list(unsigned file_id)
s.file_id = file_id; /* This is the key field for the TBBT */
- if ((node = H5TB_dfind(fs_tree, (void *)&s, NULL)) != NULL) {
- H5FP_free_file_info_node(H5TB_rem(&fs_tree->root, node, NULL));
+ if ((node = H5TB_dfind(file_info_tree, (void *)&s, NULL)) != NULL) {
+ H5FP_free_file_info_node(H5TB_rem(&file_info_tree->root, node, NULL));
ret_value = SUCCEED;
}
@@ -683,6 +665,14 @@ H5FP_remove_file_id_from_list(unsigned file_id)
*===----------------------------------------------------------------------===
*/
+/*
+ * Function: H5FP_send_reply
+ * Purpose: Send an H5FP_reply message to process TO.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 31. July, 2002
+ * Modifications:
+ */
static herr_t
H5FP_send_reply(unsigned to, unsigned req_id, unsigned file_id, H5FP_status_t status)
{
@@ -705,6 +695,76 @@ done:
}
/*
+ * Function: H5FP_dump
+ * Purpose: Dump all metadata writes to a process so that that
+ * process will write them to the file.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 31. July, 2002
+ * Modifications:
+ */
+static herr_t
+H5FP_dump(H5FP_file_info *info, unsigned to, unsigned req_id, unsigned file_id)
+{
+ H5FP_read r;
+ H5TB_NODE *node;
+ herr_t ret_value = SUCCEED;
+ int mrc;
+
+ FUNC_ENTER_NOINIT(H5FP_dump);
+
+ assert(info);
+
+ if (!info->mod_tree)
+ /* Nothing to write to the file */
+ HGOTO_DONE(SUCCEED);
+
+ r.req_id = req_id;
+ r.file_id = file_id;
+ r.status = H5FP_STATUS_DUMPING;
+
+ node = H5TB_first(info->mod_tree->root);
+
+ while (node) {
+ H5FP_mdata_mod *m = (H5FP_mdata_mod *)node->data;
+
+ r.mem_type = m->mem_type;
+ r.type_id = m->type_id;
+ r.addr = m->addr;
+ r.md_size = m->md_size;
+
+ if ((mrc = MPI_Send(&r, 1, H5FP_read_t, (int)to, H5FP_TAG_REPLY,
+ H5FP_SAP_COMM)) != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mrc);
+
+ if (H5FP_send_metadata(m->metadata, (int)m->md_size, (int)to) != SUCCEED)
+ HGOTO_ERROR(H5E_FPHDF5, H5E_CANTSENDMDATA, FAIL,
+ "can't dump metadata to client");
+
+ node = H5TB_next(node);
+ }
+
+ /* Tell the receiving process that we're finished... */
+ r.mem_type = 0;
+ r.type_id = 0;
+ r.addr = 0;
+ r.md_size = 0;
+ r.status = H5FP_STATUS_DUMPING_FINISHED;
+
+ if ((mrc = MPI_Send(&r, 1, H5FP_read_t, (int)to, H5FP_TAG_REPLY,
+ H5FP_SAP_COMM)) != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mrc);
+
+ /* Free up the modification tree */
+ H5TB_dfree(info->mod_tree, (void (*)(void*))H5FP_free_mod_node, NULL);
+ info->mod_tree = NULL;
+ info->num_mods = 0;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+/*
*===----------------------------------------------------------------------===
* Functions to handle SAP requests
*===----------------------------------------------------------------------===
@@ -735,7 +795,7 @@ H5FP_gen_sap_file_id()
* Modifications:
*/
static herr_t
-H5FP_sap_handle_open_request(H5FP_request req, char *mdata, int UNUSED md_size)
+H5FP_sap_handle_open_request(H5FP_request req, char *mdata, unsigned UNUSED md_size)
{
herr_t ret_value = SUCCEED;
int mrc;
@@ -746,11 +806,9 @@ H5FP_sap_handle_open_request(H5FP_request req, char *mdata, int UNUSED md_size)
unsigned new_file_id = H5FP_gen_sap_file_id();
int i;
- if (H5FP_add_new_file_info_to_list(new_file_id, mdata) != SUCCEED) {
- HDfree(mdata);
+ if (H5FP_add_new_file_info_to_list(new_file_id, mdata) != SUCCEED)
HGOTO_ERROR(H5E_FPHDF5, H5E_CANTINSERT, FAIL,
"can't insert new file structure to list");
- }
/* broadcast the file id to all processes */
/*
@@ -801,12 +859,12 @@ static herr_t
H5FP_sap_handle_lock_request(H5FP_request req)
{
struct lock_group {
- unsigned char oid[sizeof(req.oid)];
- unsigned file_id;
- unsigned locked;
- H5FP_lock_t rw_lock;
- H5FP_file_info *fs;
- H5FP_object_lock *lock;
+ unsigned char oid[sizeof(req.oid)];
+ unsigned file_id;
+ unsigned locked;
+ H5FP_lock_t rw_lock;
+ H5FP_file_info *info;
+ H5FP_object_lock *lock;
} *oids;
unsigned list_size = 2; /* the size of the "oids" list */
H5FP_status_t exit_state = H5FP_STATUS_LOCK_ACQUIRED;
@@ -859,19 +917,18 @@ H5FP_sap_handle_lock_request(H5FP_request req)
* not, the it's an error and we need to return.
*/
for (j = 0; j <= i; ++j) {
- if ((oids[j].fs = H5FP_find_file_info(oids[j].file_id)) == NULL) {
- /* FIXME: the file ID is invalid */
+ if ((oids[j].info = H5FP_find_file_info(oids[j].file_id)) == NULL) {
exit_state = H5FP_STATUS_BAD_FILE_ID;
HGOTO_DONE(FAIL);
}
- if (oids[j].fs->closing) {
+ if (oids[j].info->closing) {
/* we're closing the file - don't accept anymore locks */
exit_state = H5FP_STATUS_FILE_CLOSING;
HGOTO_DONE(FAIL);
}
- oids[j].lock = H5FP_find_object_lock(oids[j].fs, oids[j].oid);
+ oids[j].lock = H5FP_find_object_lock(oids[j].info, oids[j].oid);
/*
* Don't panic!
@@ -893,7 +950,7 @@ H5FP_sap_handle_lock_request(H5FP_request req)
/*
* Actually acquire the locks. This shouldn't fail because of the
- * previous check. The only thing which can likely occur is an
+ * previous checks. The only thing which can likely occur is an
* out-of-memory error.
*/
for (j = 0; j <= i; ++j) {
@@ -934,7 +991,7 @@ H5FP_sap_handle_lock_request(H5FP_request req)
req.obj_type, req.rw_lock);
if (lock) {
- if (!H5TB_dins(oids[j].fs->locks, (void *)lock, NULL)) {
+ if (!H5TB_dins(oids[j].info->locks, (void *)lock, NULL)) {
H5FP_free_object_lock(lock);
exit_state = H5FP_STATUS_LOCK_FAILED;
ret_value = FAIL;
@@ -970,7 +1027,7 @@ rollback:
if (oids[j].lock) {
if (oids[j].lock->owned_rank == req.proc_rank) {
if (--oids[j].lock->ref_count == 0) {
- H5FP_remove_object_lock_from_list(oids[j].fs, oids[j].lock);
+ H5FP_remove_object_lock_from_list(oids[j].info, oids[j].lock);
}
} else {
/* CATASTROPHIC FAILURE!!! */
@@ -1007,10 +1064,10 @@ static herr_t
H5FP_sap_handle_release_lock_request(H5FP_request req)
{
struct release_group {
- unsigned char oid[sizeof(req.oid)];
- unsigned file_id;
- H5FP_file_info *fs;
- H5FP_object_lock *lock;
+ unsigned char oid[sizeof(req.oid)];
+ unsigned file_id;
+ H5FP_file_info *info;
+ H5FP_object_lock *lock;
} *oids;
unsigned list_size = 2; /* the size of the "oids" list */
H5FP_status_t exit_state = H5FP_STATUS_LOCK_RELEASED;
@@ -1060,13 +1117,12 @@ H5FP_sap_handle_release_lock_request(H5FP_request req)
* will help keep us from being in a catastrophic state.
*/
for (j = 0; j <= i; ++j) {
- if ((oids[j].fs = H5FP_find_file_info(oids[j].file_id)) == NULL) {
- /* FIXME: the file ID is invalid */
+ if ((oids[j].info = H5FP_find_file_info(oids[j].file_id)) == NULL) {
exit_state = H5FP_STATUS_BAD_FILE_ID;
HGOTO_DONE(FAIL);
}
- oids[j].lock = H5FP_find_object_lock(oids[j].fs, oids[j].oid);
+ oids[j].lock = H5FP_find_object_lock(oids[j].info, oids[j].oid);
if (!oids[j].lock || oids[j].lock->owned_rank != req.proc_rank) {
exit_state = H5FP_STATUS_BAD_LOCK;
@@ -1083,7 +1139,7 @@ H5FP_sap_handle_release_lock_request(H5FP_request req)
if (oids[j].lock) {
if (oids[j].lock->owned_rank == req.proc_rank) {
if (--oids[j].lock->ref_count == 0)
- H5FP_remove_object_lock_from_list(oids[j].fs, oids[j].lock);
+ H5FP_remove_object_lock_from_list(oids[j].info, oids[j].lock);
} else {
/* AAAIIIIEEE!!! */
exit_state = H5FP_STATUS_CATASTROPHIC;
@@ -1103,61 +1159,6 @@ done:
}
/*
- * Function: H5FP_sap_handle_write_request
- * Purpose: Handle a request to write a piece of metadata in the
- * file.
- * Return: Success: SUCCEED
- * Failure: FAIL
- * Programmer: Bill Wendling, 06. August, 2002
- * Modifications:
- */
-static herr_t
-H5FP_sap_handle_write_request(H5FP_request req, char *mdata, int md_size)
-{
- H5FP_file_info *fs;
- H5FP_status_t exit_state = H5FP_STATUS_OK;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOINIT(H5FP_sap_handle_write_request);
-
- if ((fs = H5FP_find_file_info(req.file_id)) != NULL) {
- if (fs->closing) {
- /* we're closing the file - don't accept anymore changes */
- exit_state = H5FP_STATUS_FILE_CLOSING;
- ret_value = FAIL;
- } else {
- /* handle the change request */
- H5FP_object_lock *lock = H5FP_find_object_lock(fs, req.oid);
-
- if (!lock || lock->owned_rank != req.proc_rank
- || lock->rw_lock != H5FP_LOCK_WRITE) {
- /*
- * There isn't a write lock or we don't own the write
- * lock on this OID
- */
- exit_state = H5FP_STATUS_NO_LOCK;
- ret_value = FAIL;
- } else if (H5FP_add_file_mod_to_list(fs, req.type_id, req.addr,
- req.proc_rank, md_size,
- mdata) != SUCCEED) {
- exit_state = H5FP_STATUS_OOM;
- ret_value = FAIL;
- }
- }
- } else {
- /* error: there isn't a file opened to change */
- exit_state = H5FP_STATUS_BAD_FILE_ID;
- ret_value = FAIL;
- }
-
- if (ret_value == FAIL)
- HDfree(mdata);
-
- H5FP_send_reply(req.proc_rank, req.req_id, req.file_id, exit_state);
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-/*
* Function: H5FP_sap_handle_read_request
* Purpose: Handle a read request from a client. The bit of metadata
* that the client wants may or may not be in here. It's not
@@ -1171,7 +1172,7 @@ H5FP_sap_handle_write_request(H5FP_request req, char *mdata, int md_size)
static herr_t
H5FP_sap_handle_read_request(H5FP_request req)
{
- H5FP_file_info *fs;
+ H5FP_file_info *info;
H5FP_read r;
herr_t ret_value = SUCCEED;
char *metadata = NULL;
@@ -1186,13 +1187,25 @@ H5FP_sap_handle_read_request(H5FP_request req)
r.addr = 0;
r.status = H5FP_STATUS_MDATA_NOT_CACHED;
- if ((fs = H5FP_find_file_info(req.file_id)) != NULL) {
+ if ((info = H5FP_find_file_info(req.file_id)) != NULL) {
H5FP_mdata_mod mod; /* Used to find the correct modification */
H5TB_NODE *node;
+ if (info->num_mods >= H5FP_MDATA_CACHE_HIGHWATER_MARK) {
+ if (H5FP_dump(info, req.proc_rank, req.req_id, req.file_id) == FAIL)
+ HGOTO_ERROR(H5E_FPHDF5, H5E_CANTSENDMDATA, FAIL,
+ "can't dump metadata to client");
+
+ /*
+ * We aren't going to find the information we need since it
+ * was just dumped.
+ */
+ HGOTO_DONE(SUCCEED);
+ }
+
mod.addr = req.addr; /* This is the key field for the TBBT */
- if ((node = H5TB_dfind(fs->mod_tree, (void *)&mod, NULL)) != NULL) {
+ if ((node = H5TB_dfind(info->mod_tree, (void *)&mod, NULL)) != NULL) {
H5FP_mdata_mod *fm = (H5FP_mdata_mod *)node->data;
r.md_size = fm->md_size;
@@ -1217,6 +1230,78 @@ done:
}
/*
+ * Function: H5FP_sap_handle_write_request
+ * Purpose: Handle a request to write a piece of metadata in the
+ * file.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 06. August, 2002
+ * Modifications:
+ */
+static herr_t
+H5FP_sap_handle_write_request(H5FP_request req, char *mdata, unsigned md_size)
+{
+ H5FP_file_info *info;
+ H5FP_status_t exit_state = H5FP_STATUS_OK;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOINIT(H5FP_sap_handle_write_request);
+
+ if ((info = H5FP_find_file_info(req.file_id)) != NULL) {
+ if (info->num_mods >= H5FP_MDATA_CACHE_HIGHWATER_MARK) {
+ /*
+ * If there are any modifications not written out yet, dump
+ * them to this process
+ */
+ if (H5FP_send_reply(req.proc_rank, req.req_id, req.file_id,
+ H5FP_STATUS_DUMPING) == FAIL) {
+ exit_state = H5FP_STATUS_DUMPING_FAILED;
+ HGOTO_ERROR(H5E_FPHDF5, H5E_CANTSENDMDATA, FAIL,
+ "can't send message to client");
+ }
+
+ if (H5FP_dump(info, req.proc_rank, req.req_id, req.file_id) == FAIL) {
+ exit_state = H5FP_STATUS_DUMPING_FAILED;
+ HGOTO_ERROR(H5E_FPHDF5, H5E_CANTSENDMDATA, FAIL,
+ "metadata dump failed");
+ }
+ }
+
+ if (info->closing) {
+ /* we're closing the file - don't accept anymore changes */
+ exit_state = H5FP_STATUS_FILE_CLOSING;
+ ret_value = FAIL;
+ } else {
+ /* handle the change request */
+ H5FP_object_lock *lock = H5FP_find_object_lock(info, req.oid);
+
+ if (!lock || lock->owned_rank != req.proc_rank
+ || lock->rw_lock != H5FP_LOCK_WRITE) {
+ /*
+ * There isn't a write lock or we don't own the write
+ * lock on this OID
+ */
+ exit_state = H5FP_STATUS_NO_LOCK;
+ ret_value = FAIL;
+ } else if (H5FP_add_file_mod_to_list(info, req.mem_type, req.type_id,
+ req.addr, req.proc_rank, md_size,
+ mdata) != SUCCEED) {
+ exit_state = H5FP_STATUS_OOM;
+ ret_value = FAIL;
+ }
+ }
+ } else {
+ /* error: there isn't a file opened to change */
+ exit_state = H5FP_STATUS_BAD_FILE_ID;
+ ret_value = FAIL;
+ }
+
+done:
+ H5FP_send_reply(req.proc_rank, req.req_id, req.file_id, exit_state);
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+/*
* Function: H5FP_sap_handle_close_request
* Purpose: Handle a request to close a file.
* Return: Success: SUCCEED
@@ -1227,19 +1312,43 @@ done:
static herr_t
H5FP_sap_handle_close_request(H5FP_request req)
{
- H5FP_file_info *fs;
+ H5FP_file_info *info;
+ H5FP_status_t exit_state = H5FP_STATUS_OK;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOINIT(H5FP_sap_handle_close_request);
- if ((fs = H5FP_find_file_info(req.file_id)) != NULL)
- if (++fs->closing == H5FP_comm_size - 1)
+ if ((info = H5FP_find_file_info(req.file_id)) != NULL) {
+ if (info->num_mods) {
+ /*
+ * If there are any modifications not written out yet, dump
+ * them to this process
+ */
+ if (H5FP_send_reply(req.proc_rank, req.req_id, req.file_id,
+ H5FP_STATUS_DUMPING) == FAIL) {
+ exit_state = H5FP_STATUS_DUMPING_FAILED;
+ HGOTO_ERROR(H5E_FPHDF5, H5E_CANTSENDMDATA, FAIL,
+ "can't send message to client");
+ }
+
+ if (H5FP_dump(info, req.proc_rank, req.req_id, req.file_id) == FAIL) {
+ exit_state = H5FP_STATUS_DUMPING_FAILED;
+ HGOTO_ERROR(H5E_FPHDF5, H5E_CANTSENDMDATA, FAIL,
+ "can't dump metadata to client");
+ }
+ }
+
+ if (++info->closing == H5FP_comm_size - 1)
/* all processes have closed the file - remove it from list */
- if (H5FP_remove_file_id_from_list(req.file_id) != SUCCEED)
+ if (H5FP_remove_file_id_from_list(req.file_id) != SUCCEED) {
+ exit_state = H5FP_STATUS_BAD_FILE_ID;
HGOTO_ERROR(H5E_FPHDF5, H5E_NOTFOUND, FAIL,
"cannot remove file ID from list");
+ }
+ }
done:
+ H5FP_send_reply(req.proc_rank, req.req_id, req.file_id, exit_state);
FUNC_LEAVE_NOAPI(ret_value);
}