/* Check base speed of MST message passing 
 * Usage:
 *	testmst iterations io_size [fname]
 *
 * If fname present, file is opened each iteration.
 *      
 */

#include <stdio.h>
#include <stdlib.h>
#include "pthread_1c_np.h"
#include "tutil.h"
#include "message_service.h"
#include "file_access.h"
int http_reentrant_c_rtl;
int (* tlog_putlog_cb) (int, char * );

int echo_message ( mst_link_t link, char *service,
	char *info, int ndx, int avail )
{
    int size, status, written;
    char buffer[20000];
printf("Service %s entered, info: '%s', ndx: %d/%d\n",service, info,ndx,avail );
    while ( 1&mst_read ( link, buffer, sizeof(buffer), &size ) ) {
	if ( buffer[0] ) {  /* buffer is filename to read */
	    void *tmp;
	    int i, fsize;
	    unsigned int mdate, cdate, uic;

	    tmp = tf_open ( buffer, "r", &buffer[200] );
	    status = tf_header_info ( tmp, &fsize, &uic, &cdate, &mdate );
	    for ( i = 0; 0 < tf_read(tmp, &buffer[200], 1000); i++ );
	    tf_close(tmp);
	}
	status = mst_write ( link, buffer, size, &written );
	if ( (1&status) == 0 ) break;
    }
    mst_close ( link );
    return 1;
}
int discard_message ( mst_link_t link, char *service,
	char *info, int ndx, int avail )
{
    int size, status, written;
    char buffer[20000];
    while ( 1&mst_read ( link, buffer, sizeof(buffer), &size ) ) {
    }
    mst_close ( link );
    return 1;
}
int tlog_putlog ( int level, char *fmt ) { return 0; }

int main ( int argc, char **argv )
{
    int status, size, iterations, i, io_size, pool_id;
    int LIB$INIT_TIMER(), LIB$SHOW_TIMER();
    mst_link_t link;
    pthread_attr_t pool_attr;
    char *envval, *tfile, buffer[20000];
    
    envval = getenv("HTTP_REENTRANT_C_RTL");
#if defined(DAVEONLY)
printf("DAVEONLY defined\n");
#else
printf("DAVEONLY not defined\n");
#endif
    tlog_putlog_cb = &tlog_putlog;
#ifdef __DECC
    http_reentrant_c_rtl = envval ? atoi ( envval ) : 1;
    if ( http_reentrant_c_rtl ) {
        decc$set_reentrancy ( C$C_MULTITHREAD );
        printf("Set DECC library for multi-thread use!/" );
    }
#else
    http_reentrant_c_rtl = envval ? atoi ( envval ) : 0;
#endif
    tf_initialize("");

    INITIALIZE_THREAD_ATTR ( &pool_attr );
    pool_id = 0;
    pthread_attr_setstacksize ( &pool_attr, 62000 );
    status = mst_create_service_pool ( pool_attr, 20, 1, &pool_id );
    printf("status of service pool create: %d, id: %d\n", status, pool_id );

    iterations=1000;
    if ( argc > 1 ) iterations = atoi(argv[1]);
    io_size = 100;
    if ( argc > 2 ) io_size = atoi(argv[2]);
    tfile = "";
    if ( argc > 3 ) { tfile = argv[3]; io_size = 1 + tu_strlen(tfile); }
    printf("Iterations: %d, io_size: %d\n", iterations, io_size );

    status = mst_register_service ( "echo", echo_message, "test", pool_id );
    printf("Registered service 'echo', status: %d\n", status );

    status = mst_register_service ( "sink", discard_message, "test", pool_id );
    printf("Registered service 'sink', status: %d\n", status );

    status = mst_connect ( argc > 4 ? argv[4] : "echo", "t1", &link );
    printf("Created thread, status; %d\n", status );
    tu_strcpy ( buffer, tfile );

    LIB$INIT_TIMER();
    for ( i = 0; i < iterations; i++ ) {
	status = mst_write ( link, buffer, io_size, &size );
	if ( (status&1) == 0 ) break;
	if ( argc <= 4 || argv[4][0] == 'e' ) {
	status = mst_read ( link, buffer, sizeof(buffer), &size );
	if ( (status&1) == 0 ) break; }
    }
    LIB$SHOW_TIMER();
    printf("exchanges: %d, final status: %d\n", i, status );
    return status;
}

