/*{ ** Name: MEgettag - Get an ME tag ** ** Description: ** Get a currently unused ME tag for memory allocation. ** ** Inputs: ** none ** ** Outputs: ** none ** ** Returns: ** u_i2 ME tag. ** >0 Success ** 0 Failure (we're out of tags or a semaphore error) ** ** Re-entrancy: ** Re-entrant ** ** Exceptions: ** none ** ** Side Effects: ** None. ** ** History: ** 7/93 (Mike S) initial version */ u_i2 MEgettag(void) { u_i2 tag; STATUS stat; /* Insure our semaphore has been iniialized */ if (!tag_sem_init) init_tag_sem(); /* ** Now lock our data strucutres. */ if ((stat = MUp_semaphore(&MEtag_sem)) != OK) { /* Some error getting semaphore. */ return 0; } if (freetaglist == NULL) { /* None free; return the next available one */ if (nexttag < MAXTAGID) tag = nexttag++; else tag = 0; } else { METAGNODE *node = freetaglist; /* ** Move this node from the list of free tags to the list of ** unused nodes. */ freetaglist = node->next; node->next = freenodelist; freenodelist = node; tag = node->tag; } (VOID)MUv_semaphore(&MEtag_sem); /* Unlock things */ return tag; }
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 ); }
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 ); }
VOID IILQgstGcaSetTrace( II_LBQ_CB *IIlbqcb, i4 action ) { IILQ_TRACE *msgtrc = &IIglbcb->iigl_msgtrc; /* ** This should work, so just ignore request if fails. */ if ( MUp_semaphore( &msgtrc->ii_tr_sem ) != OK ) return; switch( action ) { case IITRC_ON : msgtrc->ii_tr_flags |= II_TR_FILE; IIcgct1_set_trace( IIlbqcb->ii_lq_gca, GCLINELEN, (PTR)&msgtrc->ii_tr_sem, IILQgwtGcaWriteTrace ); break; case IITRC_OFF : msgtrc->ii_tr_flags &= ~II_TR_FILE; IILQgtfGcaTraceFile( IIlbqcb, IITRC_OFF ); if ( ! (msgtrc->ii_tr_flags & II_TR_HDLR) ) IIcgct1_set_trace( IIlbqcb->ii_lq_gca, 0, NULL, NULL ); break; case IITRC_HDLON : if ( msgtrc->ii_num_hdlrs ) { msgtrc->ii_tr_flags |= II_TR_HDLR; IIcgct1_set_trace( IIlbqcb->ii_lq_gca, GCLINELEN, (PTR)&msgtrc->ii_tr_sem, IILQgwtGcaWriteTrace ); } break; case IITRC_HDLOFF : if ( ! msgtrc->ii_num_hdlrs ) { msgtrc->ii_tr_flags &= ~II_TR_HDLR; if ( ! (msgtrc->ii_tr_flags & II_TR_FILE) ) IIcgct1_set_trace( IIlbqcb->ii_lq_gca, 0, NULL, NULL ); } break; case IITRC_SWITCH : if ( msgtrc->ii_tr_flags & (II_TR_FILE | II_TR_HDLR) ) IIcgct1_set_trace( IIlbqcb->ii_lq_gca, GCLINELEN, (PTR)&msgtrc->ii_tr_sem, IILQgwtGcaWriteTrace ); else IIcgct1_set_trace( IIlbqcb->ii_lq_gca, 0, NULL, NULL ); break; case IITRC_RESET : IILQgtfGcaTraceFile( IIlbqcb, IITRC_OFF ); break; } MUv_semaphore( &msgtrc->ii_tr_sem ); return; }