theLink 10.0 NHI1 - theKernel - theLink - theConfig - theSq3Lite - theCompiler - theBrain - theGuard
c - tcl - cs - py - rb - jv - cc
Loading...
Searching...
No Matches
MqLalS Struct Reference

Interface between MqContextS and the Operating-System … More...

#include <LibMqMsgque_mq.h>

+ Collaboration diagram for MqLalS:

Data Fields

MqSysSelectF SysSelect
 select syscall …
 
MqSysServerSpawnF MqSysServerSpawnCB
 spawn server create syscall with libmqmsgque error plugin
 
MqSysServerThreadF MqSysServerThreadCB
 thread server create syscall with libmqmsgque error plugin
 
MqSysServerForkF MqSysServerForkCB
 fork server create syscall with libmqmsgque error plugin
 

Detailed Description

Interface between MqContextS and the Operating-System …

Definition at line 2754 of file LibMqMsgque_mq.h.

Field Documentation

◆ MqSysServerForkCB

MqSysServerForkF MqLalS::MqSysServerForkCB

fork server create syscall with libmqmsgque error plugin

Parameters
[in]mkrtthe MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only)
[in]mqrtthe MqRuntimeS instance to work on - the runtime argument, used by MQ_RT_CALL (C-only)
[in]ctxthe MqContextS instance to work on
[in,out]factoryserver configuration (memory will be freed)
[in]argsPcommand-line arguments before MK_ALFA, owned by SysServerThread
[in]namethe name of the thread
[in]socketthe name of the socket the ne FORK have to listen
[out]idPtrOutthe process identifier, pointer is not MK_NULL
Returns
The MkErrorE status from the DEFAULT MkErrorC in MkRuntimeS::error_mk

Example:

static enum MkErrorE sSysServerFork (
MkErrorE
MQ_CTX const context,
struct MqFactoryS* factory,
struct MkBufferListS ** argvP,
MK_STRN name,
MQ_SOCK_HDL socket,
struct MkIdS * idP
) {
#if defined(HAVE_FORK)
//M0
//printSTACK_0();
// fork setup !before! a fork is created
if (MqContextCT_X(context)->fParentBeforeFork) {
(*MqContextCT_X(context)->fParentBeforeFork)(context);
}
//printULSS1(*argvP);
// this is used for a filter pipeline like "| atool split .. @ cut ... @ join ..."
// argv[0] is set by the tool (cut or join) and need !not! be set by name
MkErrorCheck(pMkSysFork(MK_RT_CALL MkOBJ(context),idP));
if ((*idP).val == 0UL) {
// prevent the "client-context" from deleting in the new process
// reason: perl has a garbage collection, after fork this "context" is in the
// new process but with an invalid "event-link" (pIoCreate was done but pIoconnect not)
// and "ppMqEventCreate" can not set the "MqContextDelete_LOCK"
context->bits.MqContextDelete_LOCK = true;
// cleanup "events" after FORK
MkErrorCheck(pEventAfterFork(MQ_RT_CALL context));
// child AFTER fork
if (MqContextCT_X(context)->fChildAfterFork) (*MqContextCT_X(context)->fChildAfterFork)(context);
// setup new context
MQ_CTX newctx = NULL;
// create the new context
//M1
//MqFactoryLog_1(factory);
check_MkErrorE(MqFactoryInvoke (context, MQ_FACTORY_NEW_FORK, factory, &newctx)) goto error1;
//M2
//printC(MqClassIdentGet(newctx))
// add my configuration
newctx->statusIs = (enum MqStatusIsEF) (newctx->statusIs | MQ_STATUS_IS_FORK);
// the new CONTEXT is always a SERVER
newctx->setup.isServer = true;
// BUG-FIX: worker-2-1-0-
// DESCR: display-lock inherited from "client" disable prefix-name-setting on "server"
// -> "spawn" does NOT inherited locking at all
newctx->config.bits.dispNameLOCK = false;
newctx->config.bits.storageFileLOCK = false;
newctx->config.bits.dispPrefixLOCK= false;
newctx->config.bits.dispPostfixLOCK= false;
// BUG-FIX: error-6-ERR8-1-
// TEST: Nhi1Exec error.test --lang-ruby --block-6 -match error-6-ERR8-1-*
// ANALYSE: On FORK the refCount management (MK_RT_REF.cid, MK_RT_REF.cidA, MK_RT_REF.cidN) is already used by
// CALLING context (client). On RUBY the EXIT from the FORK (server) process does NOT intermedialtly stop
// because the rb_exit is used. This rb_exit do some RUBY cleanup and later on step back to the invalid
// CALLING (client!!) code in the FORKED (server) process. this code has now an UNBALENCED MK_RT_REF.cid
// and create and error.
// FIX: delete the calling context from the MK_RT_REF.cid
// UPDATE: this crash C… and propably more. PROBLEN is now RUBY→rb_exit
//pRefDecrO(MK_RT_CALL MkObj(MK_RT_REF.cid), __func__);
// configure the link
// 1. ---duplicate
pConfigSetDuplicate (newctx);
// 2. ---pipe-socket HDL
MqConfigSetIoPipe (newctx, socket);
// 3. --thread
// create link
check_MkErrorE (MqLinkCreate(newctx,*argvP)) goto error1;
// the MqProcessEvent is necessary because "ParentCreate" have to come back
// ifNot: java create object will fail
if (newctx->setup.isServer == true) {
}
error1:
MqExit_1(newctx);
} else {
// parend AFTER fork
if (MqContextCT_X(context)->fParentAfterFork) (*MqContextCT_X(context)->fParentAfterFork)(context);
}
pBflDelete_NULL((*argvP));
// do not create a "defunc" process
// this is "client" code… no "IgnorSIGCHLD" in client
//MkErrorCheck (MkSysIgnorSIGCHLD(context));
return MK_OK;
error:
return MkErrorDbV_1_XS (MK_ERROR_CAN_NOT_START_SERVER, name);
#else
return MkErrorDbV_1_XS (MK_ERROR_NOT_SUPPORTED, "sSysServerFork");
MK_TIMEOUT_USER
MK_OK
const MK_STRB * MK_STRN
#define MkOBJ(x)
#define MK_RT_CALL
#define MqContextCT_X(instance)
cast from an instance into the MqCtxTypeS-class-type …
#define MqConfigSetIoPipe(...)
#define MqConfigSetStartAs_E(...)
#define MqProcessEvent(...)
#define MqExit_1(ctx)
MqStatusIsEF
Information about how the context was created.
@ MQ_FACTORY_NEW_FORK
create object as a fork process
@ MQ_WAIT_FOREVER
Wait maximum timeout seconds for an event or raise an timeout-error …
@ MQ_START_FORK
create entity as fork
@ MQ_STATUS_IS_FORK
context is created as a fork
int MQ_SOCK_HDL
#define MQ_RT_ARGS
#define MQ_RT_CALL
bool dispPrefixLOCK
protect prefix
bool storageFileLOCK
protect storage
bool dispNameLOCK
protect name
struct MqConfigS::@2 bits
boolean bit-fields
bool dispPostfixLOCK
protect postfix
PUBLIC data structure for the libmqmsgque-specific-data
struct MqSetupS setup
the setup data is used to link the object with the user application
enum MqStatusIsEF statusIs
how the context was created?
const struct MqConfigS config
the configuration data is used for "end-user" configuration
data used to define a factory
bool isServer
change the context to act as server-context (MK_YES) or not (MK_NO) …
#endif /* HAVE_FORK */
}

Definition at line 2765 of file LibMqMsgque_mq.h.

◆ MqSysServerSpawnCB

MqSysServerSpawnF MqLalS::MqSysServerSpawnCB

spawn server create syscall with libmqmsgque error plugin

Parameters
[in]mkrtthe MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only)
[in]mqrtthe MqRuntimeS instance to work on - the runtime argument, used by MQ_RT_CALL (C-only)
[in]ctxthe MqContextS instance to work on
[in]argvcommand-line arguments
[in]namethe name of the process
[out]idPtrOutthe process identifier, pointer is not MK_NULL
Returns
The MkErrorE status from the DEFAULT MkErrorC in MkRuntimeS::error_mk

Example:

static enum MkErrorE sSysServerSpawn (
MQ_CTX const context,
char *const *argv,
MK_STRN name,
struct MkIdS * idP
) {
pid_t pid;
MK_STRN cmd="sSysServerSpawn";
int err=0;
// spawn setup !before! a spawn is created
if (MqContextCT_X(context)->fSpawnInit) (*MqContextCT_X(context)->fSpawnInit)(context);
#if defined(META_IS_POSIX)
// get the PATH of "name"… search the "PATH" environment variable
char path[PATH_MAX+1];
if (findpathof(path,name) == 0) {
cmd="findpathof";
goto error;
}
// perl !need! sigschiled enabled at startup make it the default
#if defined(HAVE_POSIX_SPAWN)
{
posix_spawnattr_t sa;
if ((err=posix_spawnattr_init(&sa)) != 0) {
cmd="posix_spawnattr_init";
goto error;
}
// problem: posix_spawnp (using "name" as parameter) comes back with SUCCESS even if "name" has bogo data
// solution: check "name" by myselv (findpathof) and use the "non-P" version…
if (unlikely ((err=posix_spawn(&pid, path, NULL, &sa, (char *const *) argv, environ)) != 0)) {
posix_spawnattr_destroy(&sa);
cmd="posix_spawnp";
goto error;
}
if ((err=posix_spawnattr_destroy(&sa)) != 0) {
cmd="posix_spawnattr_destroy";
goto error;
}
}
goto ok;
// ./process.h:int spawnl(int mode, const char *path, const char *argv0, ...);
// ./process.h:int spawnle(int mode, const char *path, const char *argv0, ... /*, char * const *envp */);
// ./process.h:int spawnlp(int mode, const char *path, const char *argv0, ...);
// ./process.h:int spawnlpe(int mode, const char *path, const char *argv0, ... /*, char * const *envp */);
// ./process.h:int spawnv(int mode, const char *path, const char * const *argv);
// ./process.h:int spawnve(int mode, const char *path, const char * const *argv, const char * const *envp);
// ./process.h:int spawnvp(int mode, const char *path, const char * const *argv);
// ./process.h:int spawnvpe(int mode, const char *path, const char * const *argv, const char * const *envp);
#elif (defined(HAVE_FORK) || defined(HAVE_VFORK)) && defined(HAVE_EXECV)
// fork to create the child
# if defined(HAVE_VFORK)
if (unlikely ((pid = vfork()) == -1)) {
cmd="vfork";
err=errno;
goto error;
}
# elif defined(HAVE_FORK)
if (unlikely ((pid = MqSysFork()) == -1)) {
cmd="MqSysFork";
err=errno;
goto error;
}
# else
goto error;
# endif
if (pid == 0) {
// this is the child
if (execv(path, argv) == -1) {
_exit (EXIT_FAILURE);
}
// the child will never reach this
}
goto ok;
#else
# error "unable to spwawn a process"
#endif /* HAVE_POSIX_SPAWN, HAVE_FORK, HAVE_VFORK, HAVE_EXECV */
#else /* META_IS_WINDOWS */
{
char buf[2048];
char *nbuf=buf;
// build command-line, windows _spawnvp is NOT able to handle !! whitespace !!
// in path name argument
for (;*argv != NULL; argv++) {
nbuf += sprintf(nbuf, "\"%s\" ", *argv);
}
// start process
// java on windows test-cases using tcltest seems not be able to spawn new processes
// unknown reason. command line works:
// >NhiExec example.Server.java --tcp --port 7777 --spawn
errno=0;
if (unlikely ((pid = _spawnlp (_P_NOWAIT, name, buf, NULL)) == -1)) {
cmd="_spawnvp";
err = errno;
goto error;
}
goto ok;
}
#endif
ok:
(*idP).val = (MK_IDNT)pid;
(*idP).type = MK_ID_PROCESS;
// if NO child process is available an: "POSIX-no children" error is set
// this is the "client" site an a "MkSysIgnorSIGCHLD" will interact with
// a "programming-language" like TCL… → avoid it
//MkSysIgnorSIGCHLD(MK_ERROR_IGNORE);
return MK_OK;
error:
MkErrorDbV_1_XS (MK_ERROR_CAN_NOT_START_SERVER, name);
#define unlikely(x)
uintptr_t MK_IDNT
MK_ID_PROCESS
if (err != 0) {
MkErrorAppendV_2M(context, "can not '%s' -> [%i] ERR<%s>", cmd, err, strerror (err));
}
#define MkErrorAppendV_2M(m,...)

Definition at line 2759 of file LibMqMsgque_mq.h.

◆ MqSysServerThreadCB

MqSysServerThreadF MqLalS::MqSysServerThreadCB

thread server create syscall with libmqmsgque error plugin

Parameters
[in]mkrtthe MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only)
[in]ctxthe MqContextS instance to work on
[in]argPthread startup environment
[in]namethe name of the thread
[in]statestate of the thread PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE
[out]idPtrOutthe thread identifier, pointer is not MK_NULL
Returns
The MkErrorE status from the DEFAULT MkErrorC in MkRuntimeS::error_mk

Example:

static enum MkErrorE sSysServerThread (
MQ_CTX const context,
struct MqSysServerThreadMainS * const argP,
MK_STRN name,
int thread_status,
struct MkIdS * idP
) {
#if META_HAS_THREAD
mqthread_t threadId;
// after a "thread" no "fork" is possible
MqContextCT_X(context)->ignoreFork = true;
# if defined(HAVE_PTHREAD)
# define check0(cmd,...) if (cmd(__VA_ARGS__)!=0) {MkErrorSetC_1XS("Error in '" #cmd "'");goto error;}
int ret;
// thread attributes
pthread_attr_t attr;
check0(pthread_attr_init, &attr);
check0(pthread_attr_setdetachstate, &attr, thread_status);
check0(pthread_attr_setscope, &attr, PTHREAD_SCOPE_SYSTEM);
// thread setup !before! a thread was created
if (MqContextCT_X(context)->fThreadInit) (*MqContextCT_X(context)->fThreadInit)(context);
// start thread
do {
ret = pthread_create(&threadId,&attr,sSysServerThreadInit,argP);
} while (ret == EAGAIN);
// cleanup attribute
check0(pthread_attr_destroy, &attr);
if (unlikely(ret != 0)) {
MkErrorDbV_1_XS (MK_ERROR_CAN_NOT_START_SERVER, name);
goto error;
}
# else // NOT defined(HAVE_PTHREAD)
if (unlikely ( (threadId = _beginthreadex(NULL, 0, sSysServerThreadInit, argP, 0, NULL)) == 0)) {
MkErrorDbV_1_XS (MK_ERROR_CAN_NOT_START_SERVER, name);
MkErrorSysAppend (_beginthreadex, errno);
goto error;
}
# endif // defined(HAVE_PTHREAD)
// save tid
(*idP).val = (MK_IDNT)threadId;
(*idP).type = MK_ID_THREAD;
return MK_OK;
error:
pBufferStreamFree(MK_RT_CALL MkBUS(&argP->argvR));
#if MqRuntimeC_SysServerThread_size
argP->isUsed = false;
#else
#endif
return MK_ERROR;
#else // NOT META_HAS_THREAD
return MkErrorDbV_1_XS (MK_ERROR_NOT_SUPPORTED, "sSysServerThread");
#define MkBUS(x)
MK_ERROR
#define MkSysFreeNonNull(pointer)
MK_ID_THREAD
#define MK_RT_ARGS
data used to initialize a new created thread …
MkBufferStream16384R argvR
command-line arguments, owned by SysServerThread
bool isUsed
is the object used and initialisation-flag
#endif // META_HAS_THREAD
}

Definition at line 2762 of file LibMqMsgque_mq.h.

◆ SysSelect

MqSysSelectF MqLalS::SysSelect

select syscall …

read more at: man 2 select

Parameters
[in]maxthe maximum file descriptor + 1 from the read, write or except input data
[in]readset of file descriptors
[in]writeset of file descriptors
[in]exceptset of file descriptors
[in]timeoutmaximum time to wait for data

Definition at line 2756 of file LibMqMsgque_mq.h.


The documentation for this struct was generated from the following file: