From a0c93eb2ed0e9c4e68480a90f76164ef6ef92549 Mon Sep 17 00:00:00 2001 From: Albert Cheng Date: Tue, 20 Nov 2007 12:22:15 -0500 Subject: [svn-r14275] Removed all stream-vfd source code, both library and test. Updated MANIFEST of the removal too. Tested: Kagiso and smirom. --- MANIFEST | 3 - src/H5FDstream.c | 1170 ---------------------------------------------------- src/H5FDstream.h | 101 ----- test/stream_test.c | 488 ---------------------- 4 files changed, 1762 deletions(-) delete mode 100644 src/H5FDstream.c delete mode 100644 src/H5FDstream.h delete mode 100644 test/stream_test.c diff --git a/MANIFEST b/MANIFEST index 2ffe021..bc6ef0a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -509,8 +509,6 @@ ./src/H5FDsec2.h ./src/H5FDstdio.c ./src/H5FDstdio.h -./src/H5FDstream.c _DO_NOT_DISTRIBUTE_ -./src/H5FDstream.h _DO_NOT_DISTRIBUTE_ ./src/H5FDwindows.c ./src/H5FDwindows.h ./src/H5FL.c @@ -800,7 +798,6 @@ ./test/set_extent.c ./test/space_overflow.c _DO_NOT_DISTRIBUTE_ ./test/stab.c -./test/stream_test.c _DO_NOT_DISTRIBUTE_ ./test/tarray.c ./test/tarrold.h5 ./test/tattr.c diff --git a/src/H5FDstream.c b/src/H5FDstream.c deleted file mode 100644 index 82828ac..0000000 --- a/src/H5FDstream.c +++ /dev/null @@ -1,1170 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the files COPYING and Copyright.html. COPYING can be found at the root * - * of the source code distribution tree; Copyright.html can be found at the * - * root level of an installed copy of the electronic HDF5 document set and * - * is linked from the top-level documents page. It can also be found at * - * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Copyright © 2000 The author. - * The author prefers this code not be used for military purposes. - * - * - * Author: Thomas Radke - * Tuesday, September 12, 2000 - * - * Purpose: This code provides the Stream Virtual File Driver. - * It is very much based on the core VFD which keeps an - * entire HDF5 data file to be processed in main memory. - * In addition to that, the memory image of the file is - * read from/written to a socket during an open/flush operation. - * - * Modifications: - * Thomas Radke, Thursday, October 26, 2000 - * Added support for Windows. - * Catch SIGPIPE on an open socket. - * - */ - -/* Interface initialization */ -#define H5_INTERFACE_INIT_FUNC H5FD_stream_init_interface - - -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDstream.h" /* Stream file driver */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ - -/* Only build this driver if it was configured with --with-Stream-VFD */ -#ifdef H5_HAVE_STREAM - -#ifdef H5FD_STREAM_HAVE_UNIX_SOCKETS -#ifdef H5_HAVE_SYS_TYPES_H -#include /* socket stuff */ -#endif -#ifdef H5_HAVE_SYS_SOCKET_H -#include /* socket stuff */ -#endif -#include /* gethostbyname */ -#include /* socket stuff */ -#ifdef H5_HAVE_NETINET_TCP_H -#include /* socket stuff */ -#endif -#ifdef H5_HAVE_SYS_FILIO_H -#include /* socket stuff */ -#endif -#endif - -/* - * WinXP x64 does not define EWOULDBLOCK, but instead uses - * their own Windows-specific macro, so define it here. - */ - #ifdef _WIN32 - #ifndef EWOULDBLOCK - #define EWOULDBLOCK WSAEWOULDBLOCK - #endif /* EWOULDBLOCK */ - #endif /* _WIN32 */ - -#ifndef H5_HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - -/* Some useful macros */ -#ifdef MIN -#undef MIN -#endif -#ifdef MAX -#undef MAX -#endif -#define MIN(x,y) ((x) < (y) ? (x) : (y)) -#define MAX(x,y) ((x) > (y) ? (x) : (y)) - -/* Uncomment this to switch on debugging output */ -/* #define DEBUG 1 */ - -/* Define some socket stuff which is different for UNIX and Windows */ -#ifdef H5FD_STREAM_HAVE_UNIX_SOCKETS -#define H5FD_STREAM_CLOSE_SOCKET(a) close(a) -#define H5FD_STREAM_IOCTL_SOCKET(a, b, c) ioctl(a, b, c) -#define H5FD_STREAM_ERROR_CHECK(rc) ((rc) < 0) -#else -#define H5FD_STREAM_CLOSE_SOCKET(a) closesocket (a) -#define H5FD_STREAM_IOCTL_SOCKET(a, b, c) ioctlsocket (a, b, (u_long *) (c)) -#define H5FD_STREAM_ERROR_CHECK(rc) ((rc) == (SOCKET) (SOCKET_ERROR)) -#endif - - -/* The driver identification number, initialized at runtime */ -static hid_t H5FD_STREAM_g = 0; - -/* - * The description of a file belonging to this driver. The `eoa' and `eof' - * determine the amount of hdf5 address space in use and the high-water mark - * of the file (the current size of the underlying memory). - */ -typedef struct H5FD_stream_t -{ - H5FD_t pub; /* public stuff, must be first */ - H5FD_stream_fapl_t fapl; /* file access property list */ - unsigned char *mem; /* the underlying memory */ - haddr_t eoa; /* end of allocated region */ - haddr_t eof; /* current allocated size */ - H5FD_STREAM_SOCKET_TYPE socket; /* socket to write / read from */ - hbool_t dirty; /* flag indicating unflushed data */ - hbool_t internal_socket; /* flag indicating an internal socket */ -} H5FD_stream_t; - -/* Allocate memory in multiples of this size (in bytes) by default */ -#define H5FD_STREAM_INCREMENT 8192 - -/* default backlog argument for listen call */ -#define H5FD_STREAM_BACKLOG 1 - -/* number of successive ports to hunt for until bind(2) succeeds - (default 0 means no port hunting - only try the one given in the filename) */ -#define H5FD_STREAM_MAXHUNT 0 - -/* default file access property list */ -static const H5FD_stream_fapl_t default_fapl = -{ - H5FD_STREAM_INCREMENT, /* address space allocation blocksize */ - H5FD_STREAM_INVALID_SOCKET, /* no external socket descriptor */ - TRUE, /* enable I/O on socket */ - H5FD_STREAM_BACKLOG, /* default backlog for listen(2) */ - NULL, /* do not broadcast received files */ - NULL, /* argument to READ broadcast routine */ - H5FD_STREAM_MAXHUNT, /* default number of ports to hunt */ - 0 /* unknown port for unbound socket */ -}; - -/* - * These macros check for overflow of various quantities. These macros - * assume that file_offset_t is signed and haddr_t and size_t are unsigned. - * - * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' - * is too large to be represented by the second argument - * of the file seek function. - * - * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too - * large to be represented by the `size_t' type. - * - * REGION_OVERFLOW: Checks whether an address and size pair describe data - * which can be addressed entirely in memory. - */ -#ifdef H5_HAVE_LSEEK64 -# define file_offset_t off64_t -#else -# define file_offset_t off_t -#endif -#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) -#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ - ((A) & ~(haddr_t)MAXADDR)) -#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) -#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ - HADDR_UNDEF==(A)+(Z) || \ - (size_t)((A)+(Z))<(size_t)(A)) - -/* Function prototypes */ -static void *H5FD_stream_fapl_get (H5FD_t *_stream); -static H5FD_t *H5FD_stream_open (const char *name, unsigned flags, - hid_t fapl_id, haddr_t maxaddr); -static herr_t H5FD_stream_flush (H5FD_t *_stream, hid_t dxpl_id, unsigned closing); -static herr_t H5FD_stream_close (H5FD_t *_stream); -static herr_t H5FD_stream_query(const H5FD_t *_f1, unsigned long *flags); -static haddr_t H5FD_stream_get_eoa (const H5FD_t *_stream, H5FD_mem_t type); -static herr_t H5FD_stream_set_eoa (H5FD_t *_stream, H5FD_mem_t type, haddr_t addr); -static haddr_t H5FD_stream_get_eof (const H5FD_t *_stream); -static herr_t H5FD_stream_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle); -static herr_t H5FD_stream_read (H5FD_t *_stream, H5FD_mem_t type, - hid_t fapl_id, haddr_t addr, - size_t size, void *buf); -static herr_t H5FD_stream_write (H5FD_t *_stream, H5FD_mem_t type, - hid_t fapl_id, haddr_t addr, - size_t size, const void *buf); - -/* The Stream VFD's class information structure */ -static const H5FD_class_t H5FD_stream_g = { - "stream", /*name */ - MAXADDR, /*maxaddr */ - H5F_CLOSE_WEAK, /*fc_degree */ - NULL, /*sb_size */ - NULL, /*sb_encode */ - NULL, /*sb_decode */ - sizeof (H5FD_stream_fapl_t), /*fapl_size */ - H5FD_stream_fapl_get, /*fapl_get */ - NULL, /*fapl_copy */ - NULL, /*fapl_free */ - 0, /*dxpl_size */ - NULL, /*dxpl_copy */ - NULL, /*dxpl_free */ - H5FD_stream_open, /*open */ - H5FD_stream_close, /*close */ - NULL, /*cmp */ - H5FD_stream_query, /*query */ - NULL, /*alloc */ - NULL, /*free */ - H5FD_stream_get_eoa, /*get_eoa */ - H5FD_stream_set_eoa, /*set_eoa */ - H5FD_stream_get_eof, /*get_eof */ - H5FD_stream_get_handle, /*get_handle */ - H5FD_stream_read, /*read */ - H5FD_stream_write, /*write */ - H5FD_stream_flush, /*flush */ - NULL, /*lock */ - NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ -}; - - -/*-------------------------------------------------------------------------- -NAME - H5FD_stream_init_interface -- Initialize interface-specific information -USAGE - herr_t H5FD_stream_init_interface() - -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. (Just calls - H5FD_stream_init currently). - ---------------------------------------------------------------------------*/ -static herr_t -H5FD_stream_init_interface(void) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_stream_init_interface) - - FUNC_LEAVE_NOAPI(H5FD_stream_init()) -} /* H5FD_stream_init_interface() */ - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_init - * - * Purpose: Initialize this driver by registering it with the library. - * - * Return: Success: The driver ID for the Stream driver. - * Failure: Negative. - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hid_t H5FD_stream_init (void) -{ - hid_t ret_value=H5FD_STREAM_g; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_init, FAIL) - - if (H5I_VFL != H5Iget_type (H5FD_STREAM_g)) { - H5FD_STREAM_g = H5FD_register (&H5FD_stream_g,sizeof(H5FD_class_t)); - - /* set the process signal mask to ignore SIGPIPE signals */ - /* NOTE: Windows doesn't know SIGPIPE signals that's why the #ifdef */ -#ifdef SIGPIPE - if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) - fprintf (stderr, "Stream VFD warning: failed to set the process signal " - "mask to ignore SIGPIPE signals\n"); -#endif - } - - /* Set return value */ - ret_value=H5FD_STREAM_g; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*--------------------------------------------------------------------------- - * Function: H5FD_stream_term - * - * Purpose: Shut down the VFD - * - * Return: - * - * Programmer: Quincey Koziol - * Friday, Jan 30, 2004 - * - * Modification: - * - *--------------------------------------------------------------------------- - */ -void -H5FD_stream_term(void) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_stream_term) - - /* Reset VFL ID */ - H5FD_STREAM_g=0; - - FUNC_LEAVE_NOAPI_VOID -} /* end H5FD_stream_term() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pset_fapl_stream - * - * Purpose: Modify the file access property list to use the Stream - * driver defined in this source file. The INCREMENT specifies - * how much to grow the memory each time we need more. - * If a valid socket argument is given this will be used - * by the driver instead of parsing the 'hostname:port' filename - * and opening a socket internally. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t H5Pset_fapl_stream (hid_t fapl_id, H5FD_stream_fapl_t *fapl) -{ - H5FD_stream_fapl_t user_fapl; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pset_fapl_stream, FAIL) - H5TRACE2 ("e", "ix", fapl_id, fapl); - - if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) - HGOTO_ERROR (H5E_PLIST, H5E_BADTYPE, FAIL, "not a fapl") - - if (fapl) { - if (! fapl->do_socket_io && fapl->broadcast_fn == NULL) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "read broadcast function pointer is NULL") - - user_fapl = *fapl; - if (fapl->increment == 0) - user_fapl.increment = H5FD_STREAM_INCREMENT; - user_fapl.port = 0; - ret_value = H5P_set_driver (plist, H5FD_STREAM, &user_fapl); - } - else - ret_value = H5P_set_driver (plist, H5FD_STREAM, &default_fapl); - -done: - FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_fapl_stream - * - * Purpose: Queries properties set by the H5Pset_fapl_stream() function. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t H5Pget_fapl_stream(hid_t fapl_id, H5FD_stream_fapl_t *fapl /* out */) -{ - H5FD_stream_fapl_t *this_fapl; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pget_fapl_stream, FAIL) - H5TRACE2("e","ix",fapl_id,fapl); - - if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) - HGOTO_ERROR (H5E_PLIST, H5E_BADTYPE, FAIL, "not a fapl") - if (H5FD_STREAM != H5P_get_driver (plist)) - HGOTO_ERROR (H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver") - if (NULL == (this_fapl = H5P_get_driver_info (plist))) - HGOTO_ERROR (H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info") - - if (fapl) - *fapl = *this_fapl; - -done: - FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_fapl_get - * - * Purpose: Returns a copy of the file access properties - * - * Return: Success: Ptr to new file access properties - * Failure: NULL - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void * -H5FD_stream_fapl_get (H5FD_t *_stream) -{ - H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - H5FD_stream_fapl_t *fapl; - void *ret_value; - - FUNC_ENTER_NOAPI(H5FD_stream_fapl_get, NULL) - - if ((fapl = H5MM_calloc (sizeof (H5FD_stream_fapl_t))) == NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - - *fapl = stream->fapl; - - /* Set return value */ - ret_value=fapl; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -static H5FD_STREAM_SOCKET_TYPE -H5FD_stream_open_socket (const char *filename, int o_flags, - H5FD_stream_fapl_t *fapl) -{ - struct sockaddr_in server; - struct hostent *he; - H5FD_STREAM_SOCKET_TYPE sock=H5FD_STREAM_INVALID_SOCKET; - char *hostname=NULL; - unsigned short int first_port; - const char *separator, *tmp; - int on = 1; - H5FD_STREAM_SOCKET_TYPE ret_value=H5FD_STREAM_INVALID_SOCKET; - - FUNC_ENTER_NOAPI_NOINIT(H5FD_stream_open_socket) - - /* Parse "hostname:port" from filename argument */ - for (separator = filename; *separator != ':' && *separator; separator++) - ; - if (separator == filename || !*separator) { - HGOTO_ERROR(H5E_ARGS,H5E_BADVALUE,H5FD_STREAM_INVALID_SOCKET,"invalid host address") - } else { - tmp = separator; - if (! tmp[1]) - HGOTO_ERROR(H5E_ARGS,H5E_BADVALUE,H5FD_STREAM_INVALID_SOCKET,"no port number") - while (*++tmp) { - if (! isdigit (*tmp)) - HGOTO_ERROR(H5E_ARGS,H5E_BADVALUE,H5FD_STREAM_INVALID_SOCKET,"invalid port number") - } - } - - hostname = (char *) H5MM_malloc ((size_t)(separator - filename + 1)); - - /* Return if out of memory */ - if (hostname == NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"memory allocation failed") - - HDstrncpy (hostname, filename, (size_t)(separator - filename)); - hostname[separator - filename] = 0; - fapl->port = atoi (separator + 1); - - HDmemset (&server, 0, sizeof (server)); - server.sin_family = AF_INET; - server.sin_port = htons (fapl->port); - - if (! (he = gethostbyname (hostname))) { - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to get host address") - } else if (H5FD_STREAM_ERROR_CHECK (sock = socket (AF_INET, SOCK_STREAM, 0))) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to open socket") - - if (O_RDONLY == o_flags) { - HDmemcpy (&server.sin_addr, he->h_addr, (size_t)he->h_length); -#ifdef DEBUG - fprintf (stderr, "Stream VFD: connecting to host '%s' port %d\n", - hostname, fapl->port); -#endif - if (connect (sock, (struct sockaddr *) &server, (socklen_t)sizeof (server)) < 0) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to connect") - } - else { - server.sin_addr.s_addr = INADDR_ANY; - if (H5FD_STREAM_IOCTL_SOCKET (sock, (int)FIONBIO, &on) < 0) { - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to set non-blocking mode for socket") - } else if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &on, - (socklen_t)sizeof(on)) < 0) { - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to set socket option TCP_NODELAY") - } else if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, - (socklen_t)sizeof(on)) < 0) { - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to set socket option SO_REUSEADDR") - } else { - /* Try to bind the socket to the given port. - If maxhunt is given try some successive ports also. */ - first_port = fapl->port; - while (fapl->port <= first_port + fapl->maxhunt) { -#ifdef DEBUG - fprintf (stderr, "Stream VFD: binding to port %d\n", fapl->port); -#endif - server.sin_port = htons (fapl->port); - if (bind (sock, (struct sockaddr *) &server, sizeof (server)) < 0) - fapl->port++; - else - break; - } - if (fapl->port > first_port + fapl->maxhunt) { - fapl->port = 0; - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to bind socket") - } - else if (listen (sock, fapl->backlog) < 0) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,H5FD_STREAM_INVALID_SOCKET,"unable to listen on socket") - } - } - - /* Set return value for success */ - ret_value=sock; - -done: - /* Cleanup variables */ - if(hostname!=NULL) - hostname=H5MM_xfree(hostname); - - /* Clean up on error */ - if(ret_value==H5FD_STREAM_INVALID_SOCKET) { - if (!H5FD_STREAM_ERROR_CHECK(sock)) - H5FD_STREAM_CLOSE_SOCKET(sock); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} - - -static herr_t -H5FD_stream_read_from_socket (H5FD_stream_t *stream) -{ - int size; - size_t max_size = 0; - unsigned char *ptr=NULL; - herr_t ret_value=SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT(H5FD_stream_read_from_socket) - - stream->eof = 0; - stream->mem = NULL; - - while (1) { - if (max_size <= 0) { - /* - * Allocate initial buffer as increment + 1 - * to prevent unnecessary reallocation - * if increment is exactly a multiple of the filesize - */ - max_size = stream->fapl.increment; - if (! stream->mem) - max_size++; - ptr = H5MM_realloc (stream->mem, (size_t) (stream->eof + max_size)); - if (! ptr) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"unable to allocate file space buffer") - stream->mem = ptr; - ptr += stream->eof; - } - - /* now receive the next chunk of data */ - size = recv (stream->socket, ptr, max_size, 0); - - if (size < 0 && (EINTR == errno || EAGAIN == errno || EWOULDBLOCK)) - continue; - if (size < 0) - HGOTO_ERROR(H5E_IO,H5E_READERROR,FAIL,"error reading from file from socket") - if (! size) - break; - max_size -= (size_t) size; - stream->eof += (haddr_t) size; - ptr += size; -#ifdef DEBUG - fprintf (stderr, "Stream VFD: read %d bytes (%d total) from socket\n", - size, (int) stream->eof); -#endif - } - -#ifdef DEBUG - fprintf (stderr, "Stream VFD: read total of %d bytes from socket\n", - (int) stream->eof); -#endif -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_open - * - * Purpose: Opens an HDF5 file in memory. - * - * Return: Success: A pointer to a new file data structure. The - * public fields will be initialized by the - * caller, which is always H5FD_open(). - * Failure: NULL - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5FD_t * -H5FD_stream_open (const char *filename, - unsigned flags, - hid_t fapl_id, - haddr_t maxaddr) -{ - H5FD_stream_t *stream=NULL; - const H5FD_stream_fapl_t *fapl; - int o_flags; -#ifdef _WIN32 - WSADATA wsadata; -#endif - H5P_genplist_t *plist=NULL; /* Property list pointer */ - H5FD_t *ret_value; /* Function return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_open, NULL) - - /* Check arguments */ - if (filename == NULL|| *filename == '\0') - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, NULL,"invalid file name") - if (maxaddr == 0 || HADDR_UNDEF == maxaddr) - HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr") - if (ADDR_OVERFLOW (maxaddr)) - HGOTO_ERROR (H5E_ARGS, H5E_OVERFLOW, NULL, "maxaddr overflow") - - /* Build the open flags */ - o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; - if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC; - if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT; - if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL; - - if ((O_RDWR & o_flags) && ! (O_CREAT & o_flags)) - HGOTO_ERROR (H5E_ARGS, H5E_UNSUPPORTED, NULL, "open stream for read/write not supported") - -#ifdef _WIN32 - if (WSAStartup (MAKEWORD (2, 0), &wsadata)) - HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "Couldn't start Win32 socket layer") -#endif - - fapl = NULL; - if (H5P_FILE_ACCESS_DEFAULT != fapl_id) { - if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") - fapl = H5P_get_driver_info (plist); - } - if (fapl == NULL) - fapl = &default_fapl; - - /* Create the new file struct */ - stream = (H5FD_stream_t *) H5MM_calloc (sizeof (H5FD_stream_t)); - if (stream == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") - stream->fapl = *fapl; - stream->socket = H5FD_STREAM_INVALID_SOCKET; - - /* if an external socket is provided with the file access property list - we use that, otherwise the filename argument is parsed and a socket - is opened internally */ - if (fapl->do_socket_io) { - if (! H5FD_STREAM_ERROR_CHECK (fapl->socket)) { - stream->internal_socket = FALSE; - stream->socket = fapl->socket; - } - else { - stream->internal_socket = TRUE; - stream->socket = H5FD_stream_open_socket (filename, o_flags, &stream->fapl); - if (stream->socket != H5FD_STREAM_INVALID_SOCKET) { - /* update the port ID in the file access property - so that it can be queried via H5P_get_fapl_stream() later on */ - H5P_set_driver (plist, H5FD_STREAM, &stream->fapl); - } - else - HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "can't open internal socket") - } - } - - /* read the data from socket into memory */ - if (O_RDONLY == o_flags) { - if (fapl->do_socket_io) { -#ifdef DEBUG - fprintf (stderr, "Stream VFD: reading file from socket\n"); -#endif - if(H5FD_stream_read_from_socket (stream)<0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "can't read file from socket") - } - - /* Now call the user's broadcast routine if given */ - if (fapl->broadcast_fn) { - if ((fapl->broadcast_fn) (&stream->mem, &stream->eof, - fapl->broadcast_arg) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "broadcast error") - - /* check for filesize of zero bytes */ - if (stream->eof == 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "zero filesize") - } - - /* For files which are read from a socket: - the opened socket is not needed anymore */ - if (stream->internal_socket && ! H5FD_STREAM_ERROR_CHECK (stream->socket)) - H5FD_STREAM_CLOSE_SOCKET (stream->socket); - stream->socket = H5FD_STREAM_INVALID_SOCKET; - } - - /* Set return value on success */ - ret_value=(H5FD_t*)stream; - -done: - if(ret_value==NULL) { - if(stream!=NULL) { - if (stream->mem) - H5MM_xfree (stream->mem); - if (stream->internal_socket && ! H5FD_STREAM_ERROR_CHECK (stream->socket)) - H5FD_STREAM_CLOSE_SOCKET (stream->socket); - H5MM_xfree(stream); - } /* end if */ - } - - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_flush - * - * Purpose: Flushes the file via sockets to any connected clients - * if its dirty flag is set. - * - * Return: Success: 0 - * Failure: -1 - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_stream_flush (H5FD_t *_stream, hid_t UNUSED dxpl_id, unsigned UNUSED closing) -{ - H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - size_t size; - ssize_t bytes_send; - int on = 1; - unsigned char *ptr; - struct sockaddr from; - socklen_t fromlen; - H5FD_STREAM_SOCKET_TYPE sock; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_flush, FAIL) - - /* Write to backing store */ - if (stream->dirty && ! H5FD_STREAM_ERROR_CHECK (stream->socket)) { -#ifdef DEBUG - fprintf (stderr, "Stream VFD: accepting client connections\n"); -#endif - fromlen = sizeof (from); - while (! H5FD_STREAM_ERROR_CHECK (sock = accept (stream->socket, - &from, &fromlen))) { - if (H5FD_STREAM_IOCTL_SOCKET (sock, (int)FIONBIO, &on) < 0) { - H5FD_STREAM_CLOSE_SOCKET (sock); - continue; /* continue the loop for other clients to connect */ - } - - size = stream->eof; - ptr = stream->mem; - - while (size) { - bytes_send = send (sock, ptr, size, 0); - if (bytes_send < 0) { - if (EINTR == errno || EAGAIN == errno || EWOULDBLOCK == errno) - continue; - - /* continue the outermost loop for other clients to connect */ - break; - } - ptr += bytes_send; - size -= bytes_send; -#ifdef DEBUG - fprintf (stderr, "Stream VFD: wrote %d bytes to socket, %d in total, " - "%d left\n", bytes_send, (int) (ptr - stream->mem), size); -#endif - } - H5FD_STREAM_CLOSE_SOCKET (sock); - } - stream->dirty = FALSE; - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_close - * - * Purpose: Closes the file. - * - * Return: Success: 0 - * Failure: -1 - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_stream_close (H5FD_t *_stream) -{ - H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_close, FAIL) - - /* Release resources */ - if (! H5FD_STREAM_ERROR_CHECK (stream->socket) && stream->internal_socket) - H5FD_STREAM_CLOSE_SOCKET (stream->socket); - if (stream->mem) - H5MM_xfree (stream->mem); - HDmemset (stream, 0, sizeof (H5FD_stream_t)); - H5MM_xfree (stream); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_query - * - * Purpose: Set the flags that this VFL driver is capable of supporting. - * (listed in H5FDpublic.h) - * - * Return: Success: non-negative - * - * Failure: negative - * - * Programmer: Quincey Koziol - * Tuesday, September 26, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_stream_query(const H5FD_t UNUSED * _f, - unsigned long *flags/*out*/) -{ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_query, SUCCEED) - - /* Set the VFL feature flags that this driver supports */ - if (flags) { - *flags = 0; - /* OK to perform data sieving for faster raw data reads & writes */ - *flags |= H5FD_FEAT_DATA_SIEVE; - *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_get_eoa - * - * Purpose: Gets the end-of-address marker for the file. The EOA marker - * is the first address past the last byte allocated in the - * format address space. - * - * Return: Success: The end-of-address marker. - * Failure: HADDR_UNDEF - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * - *------------------------------------------------------------------------- - */ -static haddr_t -H5FD_stream_get_eoa (const H5FD_t *_stream, H5FD_mem_t UNUSED type) -{ - const H5FD_stream_t *stream = (const H5FD_stream_t *) _stream; - haddr_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_get_eoa, HADDR_UNDEF) - - /* Set return value */ - ret_value=stream->eoa; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_set_eoa - * - * Purpose: Set the end-of-address marker for the file. This function is - * called shortly after an existing HDF5 file is opened in order - * to tell the driver where the end of the HDF5 data is located. - * - * Return: Success: 0 - * Failure: -1 - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_stream_set_eoa (H5FD_t *_stream, H5FD_mem_t UNUSED type, haddr_t addr) -{ - H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_set_eoa, FAIL) - - if (ADDR_OVERFLOW (addr)) - HGOTO_ERROR (H5E_ARGS, H5E_OVERFLOW, FAIL, "address overflow") - - stream->eoa = addr; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_get_eof - * - * Purpose: Returns the end-of-file marker, which is the greater of - * either the size of the underlying memory or the HDF5 - * end-of-address markers. - * - * Return: Success: End of file address, the first address past - * the end of the "file", either the memory - * or the HDF5 file. - * Failure: HADDR_UNDEF - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static haddr_t -H5FD_stream_get_eof (const H5FD_t *_stream) -{ - const H5FD_stream_t *stream = (const H5FD_stream_t *) _stream; - haddr_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_get_eof, HADDR_UNDEF) - - /* Set return value */ - ret_value= MAX (stream->eof, stream->eoa); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_get_handle - * - * Purpose: Returns the file handle of stream file driver. - * - * Returns: Non-negative if succeed or negative if fails. - * - * Programmer: Raymond Lu - * Sept. 16, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_stream_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle) -{ - H5FD_stream_t *file = (H5FD_stream_t *)_file; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5FD_stream_get_handle, FAIL) - - if(!file_handle) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") - - *file_handle = &(file->socket); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_read - * - * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR - * into buffer BUF according to data transfer properties in - * DXPL_ID. - * - * Return: Success: 0 - * Result is stored in caller-supplied buffer BUF - * Failure: -1 - * Contents of buffer BUF are undefined - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_stream_read (H5FD_t *_stream, - H5FD_mem_t UNUSED type, - hid_t UNUSED dxpl_id, - haddr_t addr, - size_t size, - void *buf /*out*/) -{ - H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - size_t nbytes; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_read, FAIL) - - assert (stream && stream->pub.cls); - assert (buf); - - /* Check for overflow conditions */ - if (HADDR_UNDEF == addr) - HGOTO_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed") - if (REGION_OVERFLOW (addr, size)) - HGOTO_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed") - if (addr + size > stream->eoa) - HGOTO_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed") - - /* Read the part which is before the EOF marker */ - if (addr < stream->eof) { - nbytes = MIN (size, stream->eof - addr); - HDmemcpy (buf, stream->mem + addr, nbytes); - size -= nbytes; - addr += nbytes; - buf = (char *) buf + nbytes; - } - - /* Read zeros for the part which is after the EOF markers */ - if (size > 0) - HDmemset (buf, 0, size); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5FD_stream_write - * - * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR - * from buffer BUF according to data transfer properties in - * DXPL_ID. - * - * Return: Success: Zero - * Failure: -1 - * - * Programmer: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_stream_write (H5FD_t *_stream, - H5FD_mem_t UNUSED type, - hid_t UNUSED dxpl_id, - haddr_t addr, - size_t size, - const void *buf) -{ - H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_stream_write, FAIL) - - assert (stream && stream->pub.cls); - assert (buf); - - /* Check for overflow conditions */ - if (REGION_OVERFLOW (addr, size)) - HGOTO_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed") - if (addr + size > stream->eoa) - HGOTO_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed") - - /* - * Allocate more memory if necessary, careful of overflow. Also, if the - * allocation fails then the file should remain in a usable state. Be - * careful of non-Posix realloc() that doesn't understand what to do when - * the first argument is null. - */ - if (addr + size > stream->eof) { - unsigned char *x; - haddr_t new_eof = stream->fapl.increment * - ((addr+size) / stream->fapl.increment); - - if ((addr+size) % stream->fapl.increment) - new_eof += stream->fapl.increment; - if (stream->mem == NULL) - x = H5MM_malloc ((size_t) new_eof); - else - x = H5MM_realloc (stream->mem, (size_t) new_eof); - if (x == NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block") - stream->mem = x; - stream->eof = new_eof; - } - - /* Write from BUF to memory */ - HDmemcpy (stream->mem + addr, buf, size); - stream->dirty = TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - -#endif /* H5_HAVE_STREAM */ diff --git a/src/H5FDstream.h b/src/H5FDstream.h deleted file mode 100644 index 3f3ba6a..0000000 --- a/src/H5FDstream.h +++ /dev/null @@ -1,101 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the files COPYING and Copyright.html. COPYING can be found at the root * - * of the source code distribution tree; Copyright.html can be found at the * - * root level of an installed copy of the electronic HDF5 document set and * - * is linked from the top-level documents page. It can also be found at * - * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Copyright © 2000 The author. - * The author prefers this code not be used for military purposes. - * - * - * Author: Thomas Radke - * Tuesday, September 12, 2000 - * - * Purpose: The public header file for the Stream Virtual File Driver. - * - * Modifications: - * Thomas Radke, Thursday, October 26, 2000 - * Added support for Windows. - * - */ -#ifndef H5FDstream_H -#define H5FDstream_H - -#ifdef H5_HAVE_STREAM -# define H5FD_STREAM (H5FD_stream_init()) -#else -# define H5FD_STREAM (-1) -#endif /*H5_HAVE_STREAM */ - -#ifdef H5_HAVE_STREAM -/* check what sockets type we have (Unix or Windows sockets) - Note that only MS compilers require to use Windows sockets - but gcc under Windows does not. */ -#if ! defined(H5_HAVE_WINSOCK_H) || defined(__GNUC__) -#define H5FD_STREAM_HAVE_UNIX_SOCKETS 1 -#endif - -/* define the data type for socket descriptors - and the constant indicating an invalid descriptor */ -#ifdef H5FD_STREAM_HAVE_UNIX_SOCKETS - -#define H5FD_STREAM_SOCKET_TYPE int -#define H5FD_STREAM_INVALID_SOCKET -1 - -#else -#include - -#define H5FD_STREAM_SOCKET_TYPE SOCKET -#define H5FD_STREAM_INVALID_SOCKET INVALID_SOCKET - -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -/* prototype for read broadcast callback routine */ -typedef int (*H5FD_stream_broadcast_t) (unsigned char **file, - haddr_t *len, - void *arg); - -/* driver-specific file access properties */ -typedef struct H5FD_stream_fapl_t -{ - size_t increment; /* how much to grow memory in reallocs */ - H5FD_STREAM_SOCKET_TYPE socket; /* externally provided socket descriptor*/ - hbool_t do_socket_io; /* do I/O on socket */ - int backlog; /* backlog argument for listen call */ - H5FD_stream_broadcast_t broadcast_fn; /* READ broadcast callback */ - void *broadcast_arg; /* READ broadcast callback user argument*/ - unsigned int maxhunt; /* how many more ports to try to bind to*/ - unsigned short int port; /* port a socket was bound/connected to */ -} H5FD_stream_fapl_t; - - -/* prototypes of exported functions */ -H5_DLL hid_t H5FD_stream_init (void); -H5_DLL void H5FD_stream_term(void); -H5_DLL herr_t H5Pset_fapl_stream (hid_t fapl_id, - H5FD_stream_fapl_t *fapl); -H5_DLL herr_t H5Pget_fapl_stream (hid_t fapl_id, - H5FD_stream_fapl_t *fapl /*out*/ ); - -#ifdef __cplusplus -} -#endif - -#endif /* H5_HAVE_STREAM */ - -#endif /* H5FDstream_H */ diff --git a/test/stream_test.c b/test/stream_test.c deleted file mode 100644 index 8fbdc72..0000000 --- a/test/stream_test.c +++ /dev/null @@ -1,488 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the files COPYING and Copyright.html. COPYING can be found at the root * - * of the source code distribution tree; Copyright.html can be found at the * - * root level of an installed copy of the electronic HDF5 document set and * - * is linked from the top-level documents page. It can also be found at * - * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Copyright © 2000 The author. - * The author prefers this code not be used for military purposes. - * - * - * Author: Thomas Radke - * Tuesday, September 12, 2000 - * - * Modifications: - * Thomas Radke, Thursday, October 26, 2000 - * Made it compiling under Windows. - * - */ - -/* - * This program tests the functionality of the Stream Virtual File Driver. - * 1. It spawns two new processes, a sender and a receiver. - * 2. The sender opens an HDF5 file for writing using the Stream driver. - * It will use a reserved port which should fail to be bound. - * Then it will try a couple of successive ports until bind succeeds. - * This final "hostname:port" information is written into a temporary - * file as a single line of text. - * The sender then writes a sample dataset to the HDF5 file. - * On closing the file the Stream VFD would send the file - * contents to any connected client. - * 3. The receiver serves as a client attempting to open an - * HDF5 file for reading. On opening the file the Stream VFD - * would establish a socket connection to the sender process, - * identified by its hostname and a port number (which is obtained - * from the temporary text file the sender should have created), - * and read the file contents via this socket. - * Aftwerwards the dataset is read from the file into memory - * and verified. - * 4. The main program waits for termination of its two child - * processes and returns their exit code. - */ - -#include -#include "hdf5.h" - -#ifndef H5_HAVE_STREAM - -int main (void) -{ - printf ("Test skipped because Stream Virtual File Driver not available\n"); - return (0); -} - -#elif ! defined (H5_HAVE_FORK) || ! defined (H5_HAVE_WAITPID) - -int main (void) -{ - printf ("Test skipped because this architecture doesn't provide " - "fork(2) and waitpid(2)\n"); - return (0); -} - -#else - -#include -#include -#include -#include - - -#define SLEEPTIME 10 /* sleeping time in seconds */ -#define RANK 2 /* sample dataset rank */ -#define DIMS 50 /* sample dataset dimensions */ -#define DATASETNAME "IntArray" /* sample dataset name */ -#define HOSTNAME "localhost" /* hostname of this machine */ -#define PORT "5678" /* default port to use */ -#define MAXHUNT 500 /* max number of ports to hunt */ -#define HDF5_FILENAME HOSTNAME ":" PORT /* name of the streamed file */ -#define TEMPFILENAME "stream_test.tmp" /* temporary filename */ - - -static int sender (void) -{ - int i; - hsize_t dims[RANK]; - int *data; - herr_t status; - hid_t fapl, file; - hid_t dataspace, dataset; - H5FD_stream_fapl_t stream_fapl; - FILE *tempfile; - - - /* - * Create access property list and set it to use the Stream driver. - */ - fapl = H5Pcreate (H5P_FILE_ACCESS); - if (fapl < 0) - { - fprintf (stderr, "sender: couldn't create file access property list\n"); - return (-1); - } - - /* - * Setup file access property list and select Stream VFD. - * - * - block increment for realloc() should be chosen by the driver - * - no external socket is provided (should be created internally) - * - do I/O on this processor on this socket - * - only one client is allowed to connect at a time - * - no READ broadcast function is provided (since we only send data) - * - if bind to default port (given in the filename argument) fails - * do port hunting on the following MAXHUNT ports - */ - stream_fapl.increment = 0; - stream_fapl.socket = H5FD_STREAM_INVALID_SOCKET; - stream_fapl.do_socket_io = 1; - stream_fapl.backlog = 1; - stream_fapl.broadcast_fn = NULL; - stream_fapl.broadcast_arg = NULL; - stream_fapl.maxhunt = MAXHUNT; - - status = H5Pset_fapl_stream (fapl, &stream_fapl); - if (status < 0) - { - fprintf (stderr, "sender: couldn't set file access property list " - "for Stream VFD\n"); - H5Pclose (fapl); - return (-2); - } - - /* - * Create the data space for fixed size dataset. - */ - for (i = 0; i < RANK; i++) - { - dims[i] = DIMS; - } - dataspace = H5Screate_simple (RANK, dims, NULL); - if (dataspace < 0) - { - fprintf (stderr, "sender: couldn't create dataspace\n"); - H5Pclose (fapl); - return (-3); - } - - /* - * Data buffer initialization. - */ - i = (int) H5Sget_simple_extent_npoints (dataspace); - data = (int *) malloc (i * sizeof (int)); - if (data == NULL) - { - fprintf (stderr, "sender: cannot allocate buffer for dataset with " - "%d integers\n", i); - H5Sclose (dataspace); - H5Pclose (fapl); - return (-4); - } - while (--i >= 0) - { - data[i] = i; - } - - /* - * Create a new file using H5F_ACC_TRUNC access, - * default file creation properties, and STREAM file - * access properties. - */ - printf (" sender: opening file on host '%s' port %s for writing...\n", - HOSTNAME, PORT); - file = H5Fcreate (HDF5_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - if (file < 0) - { - fprintf (stderr, "sender: couldn't create file on '%s' using port %s and " - "following %d\n", HOSTNAME, PORT, MAXHUNT); - free (data); - H5Sclose (dataspace); - H5Pclose (fapl); - return (-5); - } - - /* - * Get the file access property list to find out what port is actually used. - */ - status = H5Pget_fapl_stream (fapl, &stream_fapl); - if (status < 0) - { - fprintf (stderr, "sender: couldn't get file access property list " - "for Stream VFD\n"); - free (data); - H5Sclose (dataspace); - H5Pclose (fapl); - return (-6); - } - printf (" sender: using port %d...\n", (int) stream_fapl.port); - - /* - * Write the "hostname:port" information to a temporary file - * which can be read by the receiver process. - */ - tempfile = fopen (TEMPFILENAME, "w"); - if (tempfile == NULL) - { - fprintf (stderr, "sender: couldn't open temporary file to write " - "\"hostname:port\" information\n"); - free (data); - H5Sclose (dataspace); - H5Pclose (fapl); - return (-7); - } - fprintf (tempfile, "%s:%d", HOSTNAME, (int) stream_fapl.port); - fclose (tempfile); - - /* - * Create a new dataset within the file using defined dataspace and - * default dataset creation properties. - */ - dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, dataspace, - H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if(dataset < 0) { - fprintf(stderr, "sender: couldn't create dataset '%s'\n", DATASETNAME); - free(data); - H5Fclose(file); - H5Sclose(dataspace); - H5Pclose(fapl); - return(-8); - } - - /* - * Write the data to the dataset using default transfer properties. - */ - printf (" sender: writing dataset '%s' of type INTEGER to file '%s:%d'...\n", - DATASETNAME, HOSTNAME, (int) stream_fapl.port); - status = H5Dwrite (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, - data); - if (status < 0) - { - free (data); - H5Fclose (file); - H5Dclose (dataset); - H5Sclose (dataspace); - H5Pclose (fapl); - fprintf (stderr, "sender: couldn't write dataset\n"); - return (-9); - } - - /* - * Now give the receiver some time to connect before closing the file - * and releasing resources. - */ - printf (" sender: sleeping for %d seconds...\n", SLEEPTIME); - sleep (SLEEPTIME); - printf (" sender: closing file '%s:%d'\n", HOSTNAME, (int) stream_fapl.port); - H5Sclose (dataspace); - H5Dclose (dataset); - H5Fclose (file); - H5Pclose (fapl); - free (data); - - return (0); -} - - -static int receiver (void) -{ - int i; /* looper */ - hid_t fapl; /* file access property list */ - hid_t file; /* file handle */ - hid_t dataset; /* dataset handle */ - hid_t datatype; /* datatype handle */ - hid_t dataspace; /* dataspace handle */ - hsize_t nelems; /* total number of elements in the dataset */ - hsize_t *dims; /* dataset dimensions */ - int rank; /* dataset rank */ - int *data; /* read buffer */ - int nerrors; /* total number of errors during verify */ - int status; /* return code of HDF5 routines */ - char filename[50]; /* filename of the streamed HDF5 file */ - FILE *tempfile; /* descriptor for temporary file */ - - - /* - * Create access property list and set it to use the Stream driver. - */ - fapl = H5Pcreate (H5P_FILE_ACCESS); - if (fapl < 0) - { - fprintf (stderr, "receiver: couldn't create file access property list\n"); - return (-1); - } - - status = H5Pset_fapl_stream (fapl, NULL); - if (status < 0) - { - fprintf (stderr, "receiver: couldn't set file access property list " - "for Stream VFD\n"); - H5Pclose (fapl); - return (-2); - } - - /* - * Now give the sender some time to open the file and accepting connections. - */ - printf (" receiver: sleeping for %d seconds...\n", SLEEPTIME / 2); - sleep (SLEEPTIME / 2); - - /* - * Read the "hostname:port" information from the temporary file - * the sender should have created. - */ - tempfile = fopen (TEMPFILENAME, "r"); - if(tempfile == NULL) { - fprintf(stderr, "receiver: couldn't open temporary file to read " - "\"hostname:port\" information\n"); - H5Pclose(fapl); - return(-3); - } - fgets(filename, sizeof (filename) - 1, tempfile); - fclose(tempfile); - unlink(TEMPFILENAME); - - /* - * Open the streamed HDF5 file for reading. - */ - printf(" receiver: opening file '%s' for reading...\n", filename); - file = H5Fopen(filename, H5F_ACC_RDONLY, fapl); - H5Pclose(fapl); - if(file < 0) { - fprintf (stderr, "receiver: couldn't open file from '%s'\n", filename); - return (-4); - } - - /* - * Open the file and the dataset. - */ - printf (" receiver: reading dataset '%s'...\n", DATASETNAME); - dataset = H5Dopen2(file, DATASETNAME, H5P_DEFAULT); - if(dataset < 0) { - fprintf (stderr, "receiver: couldn't open dataset '%s'\n", DATASETNAME); - return (-5); - } - - /* - * Get dataset class, order, and size information - */ - datatype = H5Dget_type(dataset); - if(H5Tget_class(datatype) == H5T_INTEGER) - printf(" receiver: dataset is of type INTEGER\n"); - printf(" receiver: datatype size is %d bytes\n", - (int) H5Tget_size (datatype)); - printf(" receiver: byte ordering is %s endian\n", - H5Tget_order (datatype) == H5T_ORDER_LE ? "little" : "big"); - H5Tclose(datatype); - - /* - * Get dataset dimensions - */ - dataspace = H5Dget_space(dataset); - rank = H5Sget_simple_extent_ndims(dataspace); - dims = (hsize_t *)malloc(rank * sizeof (hsize_t)); - H5Sget_simple_extent_dims(dataspace, dims, NULL); - H5Sclose(dataspace); - - printf(" receiver: rank %d, dimensions %u", rank, (unsigned int)dims[0]); - nelems = dims[0]; - for (i = 1; i < rank; i++) - { - printf (" x %u", (unsigned int) dims[i]); - nelems *= dims[i]; - } - printf ("\n receiver: total number of elements: %d\n", (int) nelems); - free (dims); - - /* - * Read dataset from file into memory. - */ - data = (int *) malloc ((size_t) nelems * sizeof (int)); - status = H5Dread (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, - data); - H5Dclose (dataset); - - /* - * Close the file. - */ - printf (" receiver: closing file '%s'...\n", filename); - H5Fclose (file); - - /* - * Verify the dataset contents - */ - printf (" receiver: verifying contents of dataset '%s'...\n", DATASETNAME); - for (i = nerrors = 0; i < (int) nelems; i++) - { - if (data[i] != i) - { - fprintf (stderr, "receiver: data error at offset %d: " - "expected %d got %d\n", i, i, data[i]); - nerrors++; - } - } - printf (" receiver: dataset verified, %d errors found\n", nerrors); - - free (data); - - return (-nerrors); -} - - -int main (void) -{ - int main_status, sender_status, receiver_status; - pid_t sender_pid, receiver_pid; - - - sender_pid = receiver_pid = 0; - - /* main's return code for success */ - main_status = 0; - - /* spawn off the sender and the receiver process */ - printf ("main: starting sender process...\n"); - sender_pid = fork (); - if (sender_pid == 0) - { - return (sender ()); - } - else if (sender_pid < 0) - { - perror ("Failed to spawn sender"); - main_status = -1; - } - else - { - printf ("main: starting receiver process...\n"); - receiver_pid = fork (); - if (receiver_pid == 0) - { - return (receiver ()); - } - else if (sender_pid < 0) - { - perror ("Failed to spawn receiver"); - main_status = -1; - } - } - - /* wait for the termination of sender and receiver and check their status */ - printf ("main: waiting for termination of sender and receiver process...\n"); - if (sender_pid > 0 && - waitpid (sender_pid, &sender_status, 0) != sender_pid) - { - perror ("Failed to wait for termination of sender"); - main_status = -1; - } - else - { - main_status |= sender_status; - } - if (receiver_pid > 0 && - waitpid (receiver_pid, &receiver_status, 0) != receiver_pid) - { - perror ("Failed to wait for termination of receiver"); - main_status = -1; - } - else - { - main_status |= receiver_status; - } - - printf (main_status == 0 ? - "Stream Virtual File Driver test passed.\n" : - "*** Stream Virtual File Driver TEST FAILED ***\n"); - - return (main_status); -} - -#endif /* H5_HAVE_STREAM */ -- cgit v0.12