OCILIB (C Driver for Oracle) 3.12.1
threadkey.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2013 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: threadkey.c, Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_ThreadKeyCreateInternal
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_ThreadKey * OCI_ThreadKeyCreateInternal
00046 (
00047     POCI_THREADKEYDEST destfunc
00048 )
00049 {
00050     boolean res        = TRUE;
00051     OCI_ThreadKey *key = NULL;
00052 
00053     /* allocate key structure */
00054 
00055     key = (OCI_ThreadKey *) OCI_MemAlloc(OCI_IPC_THREADKEY, sizeof(*key), (size_t) 1, TRUE);
00056 
00057     if (key != NULL)
00058     {
00059         /* allocate error handle */
00060 
00061         res = (OCI_SUCCESS == OCI_HandleAlloc(OCILib.env,
00062                                               (dvoid **) (void *) &key->err,
00063                                               OCI_HTYPE_ERROR, (size_t) 0,
00064                                               (dvoid **) NULL));
00065 
00066         /* key initialization */
00067 
00068         OCI_CALL3
00069         (
00070             res, key->err,
00071 
00072             OCIThreadKeyInit(OCILib.env, key->err, &key->handle, destfunc)
00073         )
00074     }
00075     else
00076     {
00077         res = FALSE;
00078     }
00079 
00080     /* check errors */
00081 
00082     if (res == FALSE)
00083     {
00084         OCI_ThreadKeyFree(key);
00085         key = NULL;
00086     }
00087 
00088     return key;
00089 }
00090 
00091 /* --------------------------------------------------------------------------------------------- *
00092  * OCI_ThreadKeyFree
00093  * --------------------------------------------------------------------------------------------- */
00094 
00095 boolean OCI_ThreadKeyFree
00096 (
00097     OCI_ThreadKey *key
00098 )
00099 {
00100     boolean res = TRUE;
00101 
00102     OCI_CHECK(key == NULL, FALSE);
00103 
00104     /* close key handle */
00105 
00106     if (key->handle != NULL)
00107     {
00108         OCI_CALL0
00109         (
00110             res, key->err,
00111 
00112             OCIThreadKeyDestroy(OCILib.env, key->err, &key->handle)
00113         )
00114     }
00115 
00116     /* close error handle */
00117 
00118     if (key->err != NULL)
00119     {
00120         OCI_HandleFree(key->err, OCI_HTYPE_ERROR);
00121     }
00122 
00123     /* free key structure */
00124 
00125     OCI_FREE(key);
00126 
00127     OCI_RESULT(res);
00128 
00129     return res;
00130 }
00131 
00132 /* --------------------------------------------------------------------------------------------- *
00133  * OCI_ThreadKeySet
00134  * --------------------------------------------------------------------------------------------- */
00135 
00136 boolean OCI_ThreadKeySet
00137 (
00138     OCI_ThreadKey *key,
00139     void          *value
00140 )
00141 {
00142     boolean res = TRUE;
00143 
00144     OCI_CHECK(key == NULL, FALSE);
00145 
00146     OCI_CALL3
00147     (
00148         res, key->err,
00149 
00150         OCIThreadKeySet(OCILib.env, key->err, key->handle, value)
00151     )
00152 
00153     return res;
00154 }
00155 
00156 /* --------------------------------------------------------------------------------------------- *
00157  * OCI_ThreadKeyGet
00158  * --------------------------------------------------------------------------------------------- */
00159 
00160 boolean OCI_ThreadKeyGet
00161 (
00162     OCI_ThreadKey* key,
00163     void         **value
00164 )
00165 {
00166     boolean res = TRUE;
00167 
00168     OCI_CHECK(key == NULL, FALSE);
00169 
00170     OCI_CALL3
00171     (
00172         res, key->err,
00173 
00174         OCIThreadKeyGet(OCILib.env, key->err, key->handle, value)
00175     )
00176 
00177     return res;
00178 }
00179 
00180 /* ********************************************************************************************* *
00181  *                            PUBLIC FUNCTIONS
00182  * ********************************************************************************************* */
00183 
00184 /* --------------------------------------------------------------------------------------------- *
00185  * OCI_ThreadKeyCreate
00186  * --------------------------------------------------------------------------------------------- */
00187 
00188 boolean OCI_API OCI_ThreadKeyCreate
00189 (
00190     const mtext       *name,
00191     POCI_THREADKEYDEST destfunc
00192 )
00193 {
00194     OCI_ThreadKey *key = NULL;
00195     boolean res        = TRUE;
00196 
00197     OCI_CHECK_PTR(OCI_IPC_STRING, name, FALSE);
00198 
00199     OCI_CHECK_INITIALIZED(FALSE);
00200 
00201     if (OCILib.key_map == NULL)
00202     {
00203         /* create the map at the first call to OCI_ThreadKeyCreate to save
00204            time and memory when it's not needed */
00205 
00206         OCILib.key_map = OCI_HashCreate(OCI_HASH_DEFAULT_SIZE, OCI_HASH_POINTER);
00207 
00208     }
00209 
00210     res = (OCILib.key_map != NULL);
00211 
00212     /* create key */
00213 
00214     if (res == TRUE)
00215     {
00216         key = OCI_ThreadKeyCreateInternal(destfunc);
00217 
00218         /* add key to internal key hash table */
00219 
00220         if (key != NULL)
00221         {
00222             res = OCI_HashAddPointer(OCILib.key_map, name, key);
00223         }
00224         else
00225         {
00226             res = FALSE;
00227         }
00228     }
00229 
00230     /* check errors */
00231 
00232     if (res == FALSE)
00233     {
00234         OCI_ThreadKeyFree(key);
00235     }
00236 
00237     OCI_RESULT(res);
00238 
00239     return res;
00240 }
00241 
00242 /* --------------------------------------------------------------------------------------------- *
00243  * OCI_ThreadKeySetValue
00244  * --------------------------------------------------------------------------------------------- */
00245 
00246 boolean OCI_API OCI_ThreadKeySetValue
00247 (
00248     const mtext *name,
00249     void        *value
00250 )
00251 {
00252     boolean res        = TRUE;
00253     OCI_ThreadKey *key = NULL;
00254 
00255     OCI_CHECK_PTR(OCI_IPC_STRING, name, FALSE);
00256 
00257     key = (OCI_ThreadKey *) OCI_HashGetPointer(OCILib.key_map, name);
00258 
00259     res = OCI_ThreadKeySet(key, value);
00260 
00261     OCI_RESULT(res);
00262 
00263     return TRUE;
00264 }
00265 
00266 /* --------------------------------------------------------------------------------------------- *
00267  * OCI_ThreadKeyGetValue
00268  * --------------------------------------------------------------------------------------------- */
00269 
00270 void * OCI_API OCI_ThreadKeyGetValue
00271 (
00272     const mtext *name
00273 )
00274 {
00275     boolean res        = TRUE;
00276     void * value       = NULL;
00277     OCI_ThreadKey* key = NULL;
00278 
00279     OCI_CHECK_PTR(OCI_IPC_STRING, name, NULL);
00280 
00281     key = (OCI_ThreadKey *) OCI_HashGetPointer(OCILib.key_map, name);
00282 
00283     res = OCI_ThreadKeyGet(key, &value);
00284 
00285     OCI_RESULT(res);
00286 
00287     return value;
00288 }