コード例 #1
0
II_EXTERN IIAPI_ENVHNDL *
IIapi_initAPI( II_LONG version, II_LONG timeout )
{
    IIAPI_ENVHNDL	*envHndl;
    IIAPI_ENVHNDL	*defEnvHndl;
    II_BOOL		first_init = FALSE;
    STATUS		status;
    char		*env;

    if ( ! IIapi_static )
    {
	/*
	** Perform global initializations which are
	** environment independent.  
	*/
	first_init = TRUE;

	if ( ! ( IIapi_static = (IIAPI_STATIC *)
		 MEreqmem( 0, sizeof( IIAPI_STATIC ), TRUE, &status ) ) )
	    return( NULL );

	QUinit( &IIapi_static->api_env_q );

	if ( MUi_semaphore( &IIapi_static->api_semaphore ) != OK )
	    goto muiFail;

	if ( MEtls_create( &IIapi_static->api_thread ) != OK )
	    goto metFail;

	/*
	** Initialize sub-systems.
	*/
	IIAPI_INITTRACE();
	IIAPI_TRACE( IIAPI_TR_TRACE )( "IIapi_initAPI: initializing API.\n" );

	/*
	** Make sure II_SYSTEM or similar is set to provide useful feedback
	** rather than just failing in one of following subsystems.
	*/
	NMgtAt( SYSTEM_LOCATION_VARIABLE, &env );
	if ( env == NULL || *env == EOS )
	{
	    IIAPI_TRACE( IIAPI_TR_FATAL )
		( "IIapi_initAPI: error - %s not set.\n",
		  SYSTEM_LOCATION_VARIABLE );
	    goto adfFail;
	}
	
	IIapi_init_mib();
	if ( ! IIapi_initADF() )	goto adfFail;
	if ( ! IIapi_initGCA(timeout) )	goto gcaFail;

	/* Initialize the unicode collation values */
	IIapi_static->api_unicol_init = FALSE;
	IIapi_static->api_ucode_ctbl = NULL; 
	IIapi_static->api_ucode_cvtbl = NULL;

	/*
	** Create the default environment.
	*/
	if ( ! (IIapi_static->api_env_default = 
				(PTR)IIapi_createEnvHndl( IIAPI_VERSION_1 )) )
	    goto defFail;

	/* Spoken Language to use */

    	if( ( status = ERlangcode( (char *)NULL, 
				   &IIapi_static->api_slang ) != OK) )
    	{
	    IIAPI_TRACE( IIAPI_TR_ERROR )
		( "IIapi_initAPI: error initializing lang 0x%x\n", status );

	    return( NULL );
    	}

	/*
	** The SQL state machines are used by default prior to
	** IIapi_connect() being called, so make sure they are
	** initialized.
	*/
	if ( IIapi_sm_init( IIAPI_SMT_SQL ) != IIAPI_ST_SUCCESS )
	    goto envFail;
    }

    /*
    ** Now do environment specific initialization.
    */
    defEnvHndl = IIapi_defaultEnvHndl();

    if ( version == IIAPI_VERSION_1 )
    {
	/*
	** Version 1 initializers share the default
	** environment.  Keep track of the number of
	** initializers so that IIapi_termAPI() can
	** determine when to do global shutdown.
	*/
	envHndl = defEnvHndl;

	MUp_semaphore( &defEnvHndl->en_semaphore );
	defEnvHndl->en_initCount++;
	MUv_semaphore( &defEnvHndl->en_semaphore );
    }
    else
    {
	/*
	** Create a new environment for the initializer.
	** These environments are saved on the global
	** environment queue.  The caller may also make
	** API calls using the default environment handle, 
	** so increment the default environment handle
	** initialization count.
	*/
	if ( (envHndl = IIapi_createEnvHndl( version )) )
	{
	    MUp_semaphore( &IIapi_static->api_semaphore );
	    QUinsert( (QUEUE *)envHndl, &IIapi_static->api_env_q );
	    MUv_semaphore( &IIapi_static->api_semaphore );

	    MUp_semaphore( &defEnvHndl->en_semaphore );
	    defEnvHndl->en_initCount++;
	    MUv_semaphore( &defEnvHndl->en_semaphore );
	}
	else
	{
	    /*
	    ** We may need to undo the global initialization.
	    ** If not, the NULL environment handle will simply
	    ** be returned.
	    */
	    if ( first_init )  goto envFail;
	}
    }

    return( envHndl );

  envFail:
    IIapi_deleteEnvHndl( (IIAPI_ENVHNDL *)IIapi_static->api_env_default );

  defFail:
    IIapi_termGCA();

  gcaFail:
    IIapi_termADF();

  adfFail:
    IIAPI_TERMTRACE();
    MEtls_destroy( &IIapi_static->api_thread, NULL );

  metFail:
    MUr_semaphore( &IIapi_static->api_semaphore );

  muiFail:
    MEfree( (PTR)IIapi_static );
    IIapi_static = NULL;

    return( NULL );
}
コード例 #2
0
II_EXTERN II_BOOL
IIapi_termAPI( IIAPI_ENVHNDL *envHndl )
{
    IIAPI_ENVHNDL	*defEnvHndl;
    II_BOOL		last_term = FALSE;

    if ( ! IIapi_static )  return( TRUE );

    defEnvHndl = IIapi_defaultEnvHndl();

    if ( envHndl )  
    {
	/*
	** Free the environment handle.
	*/
	MUp_semaphore( &IIapi_static->api_semaphore );
	QUremove( (QUEUE *)envHndl );
	MUv_semaphore( &IIapi_static->api_semaphore );

	IIapi_deleteEnvHndl( envHndl );
    }
    else
    {
	/*
	** Decrement the usage counter in 
	** the default environment handle.
	*/
	MUp_semaphore( &defEnvHndl->en_semaphore );
	defEnvHndl->en_initCount = max( 0, defEnvHndl->en_initCount - 1 );
	MUv_semaphore( &defEnvHndl->en_semaphore );
    }

    /*
    ** Shutdown API when all version 1 initializers have terminated
    ** and there are no active version 2 environments.
    */
    if ( ! defEnvHndl->en_initCount  &&
         IIapi_isQueEmpty( &IIapi_static->api_env_q ) )
    {
	QUEUE		*q;

	IIAPI_TRACE( IIAPI_TR_TRACE )
	    ( "IIapi_termAPI: shutting down API completely.\n" );

	/*
	** Free the default environment.
	*/
	IIapi_deleteEnvHndl( (IIAPI_ENVHNDL *)IIapi_static->api_env_default );
	IIapi_static->api_env_default = NULL;

	/*
	** Shutdown sub-systems.
	*/
	IIapi_termGCA();
	IIapi_termADF();

	IIAPI_TRACE( IIAPI_TR_INFO )( "IIapi_termAPI: API shutdown.\n" );
	IIAPI_TERMTRACE();

	/*
	** Free the remaining global resources.
	*/
	if (IIapi_static->api_ucode_ctbl)
	  MEfree (IIapi_static->api_ucode_ctbl);
	if (IIapi_static->api_ucode_cvtbl)
	  MEfree (IIapi_static->api_ucode_cvtbl);

	MEtls_destroy( &IIapi_static->api_thread, MEfree );
	MUr_semaphore( &IIapi_static->api_semaphore );
	MEfree( (PTR)IIapi_static );
	IIapi_static = NULL;
	last_term = TRUE;
    }

    return( last_term );
}
コード例 #3
0
VOID
gca_terminate( GCA_SVC_PARMS *svc_parms )
{
    GCA_CB	*gca_cb = (GCA_CB *)svc_parms->gca_cb;
    char	id_buff[16];

    /*
    ** Increment the term counter and perform global 
    ** shutdown if all initializers have terminated.
    **
    ** The current request must be completed during
    ** global shutdown so that ACB resources can be
    ** freed.  If global shutdown is not being done,
    ** the request must still be completed to ensure
    ** a consistent state.
    */
    if ( IIGCa_global.gca_initiate > ++IIGCa_global.gca_terminate )
	gca_complete( svc_parms );
    else
    {
	i4 assoc_id;

	/*
	** Shutdown any remaining associations.
	*/
	for( 
	     assoc_id = gca_next_acb( -1 ); 
	     assoc_id >= 0;
	     assoc_id = gca_next_acb( assoc_id ) 
	   )
	{
	    /*
	    ** Skip ACB flagged for deletion since it has
	    ** already been shutdown.
	    */
	    GCA_ACB *acb = gca_find_acb( assoc_id );

	    if ( acb  &&  ! acb->flags.delete_acb )
	    {
		GCA_DA_PARMS	da_parms;
		STATUS		status;

		/*
		** TODO: Fix GC CL interface for register/llsten.
		**
		** If this association is an active listen, this
		** call will fail.  With the current interface
		** there is nothing we can do.  A GC control
		** block is needed for registration, created 
		** by GCregister() and used in GClisten(), which 
		** can then be passed to a deregister routine 
		** capable of aborting a listen and cleaning up
		** the register resources.  
		**
		** Currently, the CL must do register/listen
		** cleanup during GCterminate(), which can't be 
		** called prior to these calls here.
		*/
		da_parms.gca_association_id = assoc_id;
		IIGCa_cb_call( (PTR *)&gca_cb, GCA_DISASSOC, 
			       (GCA_PARMLIST *)&da_parms, 
			       GCA_SYNC_FLAG, NULL, -1L, &status );
	    }
	}

	/* 
	** Call GCterminate to perform system-dependent cleanup 
	*/
	GCterminate( &svc_parms->gc_parms );

	/*
	** Cleanup ACB global resources.
	**
	** There may be an ACB associated with the current
	** request.  If so, it is the registration ACB and
	** should be shutdown and flagged for deletion.  We 
	** need to perform request completion at this point
	** so that the ACB resources can be freed.
	*/
	gca_complete( svc_parms );

	/*
	** Release any remaining ACB.  Normally, there should
	** only be an active listen ACB at this point.
	*/
	for( 
	     assoc_id = gca_next_acb( -1 ); 
	     assoc_id >= 0;
	     assoc_id = gca_next_acb( assoc_id ) 
	   )
	{
	    GCA_ACB *acb = gca_find_acb( assoc_id );
	    if ( acb )  gca_del_acb( acb->assoc_id );
	}

	/*
	** Now, release the remaining ACB resources.
	*/
	gca_free_acbs();
	MUr_semaphore( &IIGCa_global.gca_acb_semaphore );

#ifdef GCF_EMBEDDED_GCN

	/* 
	** Shutdown the embedded Name Server interface 
	*/
	if ( IIGCa_global.gca_embedded_gcn )  gca_ns_term();

#endif /* GCF_EMBEDDED_GCN */

	/*
	** Shutdown security.
	*/
	IIgcs_call( GCS_OP_TERM, GCS_NO_MECH, NULL );

	IIGCa_global.gca_initialized = FALSE;
    }

    /*
    ** Tell MO that the control block is no longer active.
    */
    STprintf( id_buff, "%d", gca_cb->gca_cb_id );
    MOdetach( GCA_MIB_CLIENT, id_buff );

    /*
    ** Free resources.
    */
    MUr_semaphore( &gca_cb->gca_reg_semaphore );

    /*
    ** Clear the initialization flag so the 
    ** control block will be freed in gca_call().
    */
    gca_cb->gca_initialized = FALSE;

    return;
}