Re: GLPK 4.61: thread local storage in Windows DLL

Andrew Makhorin <[email protected]>
Newsgroups gmane.comp.gnu.glpk
Message-ID <1483993105.6473.12.camel@corvax>
Please see attached a working tls implementation for dll. It is from
some old version of glpk.



On Mon, 2017-01-09 at 20:32 +0100, Heinrich Schuchardt wrote:
> Hello David,
> 
> the thread local storage is not correctly implemented for usage with
> Windows in a DLL. See
> 
> https://msdn.microsoft.com/en-us/library/windows/desktop/ms686997
> 
> I think we should do the following:
> 
> Write a test case that demonstrates the usage of multithreading GLPK
> using the pthread library.
> 
> Add a pthread emulation for Windows so we can use the same test code
> with Windows and with Posix. For a minimalistic implementation see
> http://sqlstat.sourceforge.net/doxygen/html/sqlthread_8h_source.html
> 
> Rewrite the allocation and freeing of the env variable according to the
> Windows DLL requirements.
> 
> Best regards
> 
> Heinrich Schuchardt
>

_______________________________________________
Help-glpk mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-glpk
dlltsl.c (text/x-csrc, 4 KB)
/* glplib03.c (TLS communication) */

/***********************************************************************
*  This code is part of GLPK (GNU Linear Programming Kit).
*
*  Copyright (C) 2000, 01, 02, 03, 04, 05, 06, 07, 08 Andrew Makhorin,
*  Department for Applied Informatics, Moscow Aviation Institute,
*  Moscow, Russia. All rights reserved. E-mail: <address@hidden>.
*
*  GLPK is free software: you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  GLPK is distributed in the hope that it will be useful, but WITHOUT
*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
*  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
*  License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************/

#include "glplib.h"

#if !defined(GLP_TLS_CONFIG) || GLP_TLS_CONFIG == 0

/* platform-independent ISO C version */

static void *tls = NULL;
/* in a re-entrant version of the package this variable must be placed
   in the Thread Local Storage (TLS) */

/***********************************************************************
*  NAME
*
*  lib_set_ptr - store global pointer in TLS
*
*  SYNOPSIS
*
*  #include "glplib.h"
*  void lib_set_ptr(void *ptr);
*
*  DESCRIPTION
*
*  The routine lib_set_ptr stores a pointer specified by the parameter
*  ptr in the Thread Local Storage (TLS). */

void lib_set_ptr(void *ptr)
{     tls = ptr;
      return;
}

/***********************************************************************
*  NAME
*
*  lib_get_ptr - retrieve global pointer from TLS
*
*  SYNOPSIS
*
*  #include "glplib.h"
*  void *lib_get_ptr(void);
*
*  RETURNS
*
*  The routine lib_get_ptr returns a pointer previously stored by the
*  routine lib_set_ptr. If the latter has not been called yet, NULL is
*  returned. */

void *lib_get_ptr(void)
{     void *ptr;
      ptr = tls;
      return ptr;
}

#elif GLP_TLS_CONFIG == 1

/* there must be a version for GNU/Linux */

#elif GLP_TLS_CONFIG == 2

/* multi-threaded DLL for MSVC 6.0 */

#include <windows.h>

static DWORD dwTlsIndex;

BOOL APIENTRY DllMain
(     HINSTANCE hinstDLL,  /* DLL module handle */
      DWORD fdwReason,     /* reason called */
      LPVOID lpvReserved   /* reserved */
)
{     switch (fdwReason)
      {  /* the DLL is loading due to process initialization or a call
            to LoadLibrary */
         case DLL_PROCESS_ATTACH:
            /* allocate a TLS index */
            dwTlsIndex = TlsAlloc();
            if (dwTlsIndex == 0xFFFFFFFF) return FALSE;
            /* initialize the index for first thread */
            TlsSetValue(dwTlsIndex, NULL);
            /* initialize GLPK library environment */
            lib_init_env();
            break;
         /* the attached process creates a new thread */
         case DLL_THREAD_ATTACH:
            /* initialize the TLS index for this thread */
            TlsSetValue(dwTlsIndex, NULL);
            /* initialize GLPK library environment */
            lib_init_env();
            break;
         /* the thread of the attached process terminates */
         case DLL_THREAD_DETACH:
            /* free GLPK library environment */
            lib_free_env();
            break;
         /* the DLL is unloading due to process termination or call to
            FreeLibrary */
         case DLL_PROCESS_DETACH:
            /* free GLPK library environment */
            lib_free_env();
            /* release the TLS index */
            TlsFree(dwTlsIndex);
            break;
         default:
            break;
      }
      return TRUE;
}

void lib_set_ptr(void *ptr)
{     TlsSetValue(dwTlsIndex, ptr);
      return;
}

void *lib_get_ptr(void)
{     void *ptr;
      ptr = TlsGetValue(dwTlsIndex);
      return ptr;
}

#endif

/* eof */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.