XCore atexit

Files CCore/inc/libc/atexit.h CCore/src/libc/atexit.cpp

atexit() is a C standard function. It registers a pointer to a function to be executed after the function main(). In C++ it may also be used to register global object destructors. gcc uses the extended variant of this function __cxa_atexit.


(from stdlib.h)

/* termination */

typedef void (*__std_atexit_t)(void);

extern int atexit(__std_atexit_t func);

typedef void (*__cxa_atexit_t)(void *arg);

extern int __cxa_atexit(__cxa_atexit_t func,void *arg,void *dso);

This part provides implementation of these functions and the function Exit_atexit() to call all registered functions.


#ifndef CCore_inc_libc_atexit_h
#define CCore_inc_libc_atexit_h

namespace CCore {

/* init/exit functions */

void Exit_atexit();

} // namespace CCore

#endif

You can reuse the implementation from the Vanilla-X or create your own.


namespace CCore {

/* init/exit functions */

namespace Private_atexit {

/* struct Func */

struct Func
 {
  struct Ext
   {
    __cxa_atexit_t func;
    void *arg;
    void *dso;
   };

  __std_atexit_t func;
  Ext ext;

  static Func Create(__std_atexit_t func);

  static Func Create(__cxa_atexit_t func,void *arg,void *dso);

  void operator () ()
   {
    if( func )
      {
       func();
      }
    else
      {
       ext.func(ext.arg);
      }
   }
 };

....

bool FuncBlock::Push(const Func &func);

bool FuncBlock::Pop(Func &ret);

} // namespace Private_atexit

using namespace Private_atexit;

/* init/exit functions */

void Exit_atexit()
 {
  for(Func func; FuncBlock::Pop(func) ;) func();
 }

} // namespace CCore

using namespace CCore;

/* atexit() */

int atexit(__std_atexit_t func)
 {
  if( !func )
    {
     errno=EBADARG;

     return -1;
    }

  Dev::IntLock lock;

  return FuncBlock::Push(Func::Create(func))?0:1 ;
 }

int __cxa_atexit(__cxa_atexit_t func,void *arg,void *dso)
 {
  if( !func )
    {
     errno=EBADARG;

     return -1;
    }

  Dev::IntLock lock;

  return FuncBlock::Push(Func::Create(func,arg,dso))?0:1 ;
 }

Remember, that registration must be done under the IntLock protection.