My application is built with apache and runs on windows. I am creating a Thread using the createThread() and then for each thread executing the below :
ap_run_sub_req( subrequest );
ap_rflush( subrequest );
ap_destroy_sub_req( subrequest );
The ap_destroy_sub_request in turn calls apr_pool_destroy() function.
The ap_run_sub_req() allocated memory for pool and ap_destroy_sub_req() frees the allocated memory.
If the apr_pool_destroy() is called inside a thread then the allocated memory is not freed as a result my application is having memory leak. I couldn't find in any apache documentation any mention of apr_pool_destroy() being non-thread safe functions.
How can this problem be resolved ?? How can I free the allocated pool inside the threads?
Thanks
Here's the source code for apr_pool_destroy():
APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool)
{
apr_memnode_t *active;
apr_allocator_t *allocator;
/* Run pre destroy cleanups */
run_cleanups(&pool->pre_cleanups);
pool->pre_cleanups = NULL;
/* Destroy the subpools. The subpools will detach themselve from
* this pool thus this loop is safe and easy.
*/
while (pool->child)
apr_pool_destroy(pool->child);
/* Run cleanups */
run_cleanups(&pool->cleanups);
/* Free subprocesses */
free_proc_chain(pool->subprocesses);
/* Remove the pool from the parents child list */
if (pool->parent) {
#if APR_HAS_THREADS
apr_thread_mutex_t *mutex;
if ((mutex = apr_allocator_mutex_get(pool->parent->allocator)) != NULL)
apr_thread_mutex_lock(mutex);
#endif /* APR_HAS_THREADS */
if ((*pool->ref = pool->sibling) != NULL)
pool->sibling->ref = pool->ref;
#if APR_HAS_THREADS
if (mutex)
apr_thread_mutex_unlock(mutex);
#endif /* APR_HAS_THREADS */
}
/* Find the block attached to the pool structure. Save a copy of the
* allocator pointer, because the pool struct soon will be no more.
*/
allocator = pool->allocator;
active = pool->self;
*active->ref = NULL;
#if APR_HAS_THREADS
if (apr_allocator_owner_get(allocator) == pool) {
/* Make sure to remove the lock, since it is highly likely to
* be invalid now.
*/
apr_allocator_mutex_set(allocator, NULL);
}
#endif /* APR_HAS_THREADS */
/* Free all the nodes in the pool (including the node holding the
* pool struct), by giving them back to the allocator.
*/
allocator_free(allocator, active);
/* If this pool happens to be the owner of the allocator, free
* everything in the allocator (that includes the pool struct
* and the allocator). Don't worry about destroying the optional mutex
* in the allocator, it will have been destroyed by the cleanup function.
*/
if (apr_allocator_owner_get(allocator) == pool) {
apr_allocator_destroy(allocator);
}
}
From the looks of it, it's not thread-safe, but I'm not a C expert. You should probably post on the APR mailing list.
Related
I need to build a javascript engine (duktape or jerryscript) for a embedded device which should be capable of executing shell commands. how can this be achieved?
With duktape in C, you can easily create a native ECMAScript function and create a reference to it via the global object:
#include "duktape.h"
int main() {
/* create heap */
duk_context* heap = duk_create_heap(NULL,NULL,NULL,NULL,
NULL); /* preferably, set an error callback here */
/* push the native function on the stack */
duk_push_c_function(ctx, /* heap context */
&native_js_shell, /* native function pointer */
1); /* accepted arguments */
/* make this javascript function a property of the global object */
duk_put_global_string(ctx, /* heap context*/
"shell"); /* function name in js */
return 0;
}
/* Your native C function */
duk_ret_t native_js_shell(duk_context* ctx) {
/* obtain the argument from javascript */
const char* cmd = duk_safe_to_string(ctx, /* heap context */
-1); /* position on stack */
/* run the shell command, etc. */
/* ... */
}
All the explanation for the duk_* functions can be found in the duktape API, but perhaps this gives you an idea of how it's structured.
p.s. Welcome to Stack Overflow! Your question may have been downrated since it pretty much requires someone to write all the code for you. In general, in the future, try to do the research on your own, and ask specific questions as you get stuck. :)
I have a few datamodules, created with C++ Builder 6. Each of them uses another datamodule that initializes the connection with the database. I'm trying to make a DLL out of those datamodules.
The error is thrown on creation of DataModule_Users and says 'Abnormal program termination'.
Where do I go wrong?
Thanks in advance
datamodule_dll.bpf
USEFORM("DataModule_Connection.cpp", DataModule_Connection); /* TDataModule: File Type */
USEFORM("DataModule_Users.cpp", DataModule_Users); /*TDataModule: File Type */
//------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
DllEntryPoint
datamodule_DLL.cpp
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
extern "C" __declspec(dllexport) const char * GetUserName(const char * ID);
const char * GetUserName(const char * ID) {
CoInitialize(NULL); // datasets use COM
// This is used by DataModule_Users (normally this is done with Application->CreateForm();
DataModule_Connection = new DataModule_Connection( 0 /* Owner */ );
DataModule_Users = new DataModule_Users( 0 /* Owner */ );
return DataModule_Users->GetUserName(ID);
}
I will quote Remy Lebeau:
COM is initialized on a per-thread basis. Once a thread's COM model
(apartment vs multithreaded) has been set, it cannot be changed later.
If your DLL calls CoInitialize() before the caller does, your
parameters would take priority, which might not meet the caller's
needs. If you want to control the COM settings for your DMs without
affecting the caller, you have to move the DMs to their own thread.
Besides, DllEntryPoint() is not an appropriate place to initialize
them anyway. The OS restricts what DllEntryPoint() is allowed to do.
This solved the issue. I had to call coInitialize() before I load the library.
Please can anybody help me on this issue.
Is it possible for 2 different tasks to create 2 different semaphore for gaurding same critical resource in VxWorks?
This should be covered in the vxWorks documentation.
In general, you should decouple the creation of the semaphore from the use of the semaphore.
/**Initialization Code**/
SEM_ID semM;
semM = semMCreate (...);
...
taskSpawn(task1...);
taskSpawn(task2...);
...
/* Task 1 code */
void task1() {
...
semTake (semM, WAIT_FOREVER);
...<Task 1 critical section>
semGive (semM);
...
}
/* Task 2 code */
void task2() {
...
semTake (semM, WAIT_FOREVER);
...< Task 2 critical section>
semGive (semM);
...
}
In this instance, semM is a global variable available to both tasks.
If that offends you, with VxWorks 6.x you can also use the semOpen() API which gives semaphores names.
Do a semOpen in each task to create/retrieve the semaphore and it's ID.
When the mutex is created, it is available to the first task that does a semTake (be it task 1 or task 2).
If you need things to happen in a specific order then you need a combination of mutex (for mutual exclusion) and synchronization (via Binary semaphore for example).
Taking the above example a modifying a bit to make sure that task2 only runs once task1 has done something.
/**Initialization Code**/
SEM_ID semM;
SEM_ID semSync;
semM = semMCreate (...);
semSync = semBCreate (...);
...
void task1() {
...
/* Access Shared Structure */
semTake (semM, WAIT_FOREVER);
...<Task 1 critical section>
semGive (semM);
/* Notify Task 2 that something is available */
semGive (semSync);
...
}
void task2() {
...
/* Wait for Task 1 to let me know there is something to do */
semTake (semSync, WAIT_FOREVER);
/* Access Shared Structure */
semTake (semM, WAIT_FOREVER);
...< Task 2 critical section>
semGive (semM);
...
}
I think you missing here something,
in vxWorks, all tasks share the same memory space, therefore, you must protected global data between tasks with Mutex.
The idea is to use only one Mutex (that its sem_id is well known for all tasks that want to use it).
You can protect the data using one Mutex (there is no limitation about the number of tasks using the same Mutex).
if you do want to access the same memory space between 2 tasks in vxWorks, the best way to do it is:
create access function
int access_func(void)
{
static SEM_ID sem_id=0;
if(sem_id == 0)
{
/* create mutex semaphore \u2013 semMCreate(\u2026) */
}
return_code=semTake(sem_id, time_out);
if(return_code != 0) return errno;
/* read or write to or from global memory */
semGive(sem_id);
}
Notes:
There are several options in semMCreate and several options in semTake
You can create the mutex at the system init (recommended).
If the mutex is not read, and the sem_id is still zero, semTake return ERROR (you can check the return code and the system errno)
I am simulating a CPU and I'm doing this using high level simulation tools. SystemC is a good resource for these purposes. I'm using two modules:
DataPath
Memory
CPU datapath is modeled as a unique high level entity, however the following code will sure be better than any other explaination:
The following is datapath.hpp
SC_MODULE(DataPath) {
sc_in_clk clk;
sc_in<bool> rst;
///
/// Outgoing data from memory.
///
sc_in<w32> mem_data;
///
/// Memory read enable control signal.
///
sc_out<sc_logic> mem_ctr_memreadenable;
///
/// Memory write enable control signal.
///
sc_out<sc_logic> mem_ctr_memwriteenable;
///
/// Data to be written in memory.
///
sc_out<w32> mem_dataw; //w32 is sc_lv<32>
///
/// Address in mem to read and write.
///
sc_out<memaddr> mem_addr;
///
/// Program counter.
///
sc_signal<w32> pc;
///
/// State signal.
///
sc_signal<int> cu_state;
///
/// Other internal signals mapping registers' value.
/// ...
// Defining process functions
///
/// Clock driven process to change state.
///
void state_process();
///
/// State driven process to apply control signals.
///
void control_process();
// Constructors
SC_CTOR(DataPath) {
// Defining first process
SC_CTHREAD(state_process, clk.neg());
reset_signal_is(this->rst, true);
// Defining second process
SC_METHOD(control_process);
sensitive << (this->cu_state) << (this->rst);
}
// Defining general functions
void reset_signals();
};
The following is datapath.cpp
void DataPath::state_process() {
// Useful variables
w32 ir_value; /* Placing here IR register value */
// Initialization phase
this->cu_state.write(StateFetch); /* StateFetch is a constant */
wait(); /* Wait next clock fall edge */
// Cycling
for (;;) {
// Checking state
switch (this->cu_state.read()) { // Basing on state, let's change the next one
case StateFetch: /* FETCH */
this->cu_state.write(StateDecode); /* Transition to DECODE */
break;
case StateDecode: /* DECODE */
// Doing decode
break;
case StateExecR: /* EXEC R */
// For every state, manage transition to the next state
break;
//...
//...
default: /* Possible not recognized state */
this->cu_state.write(StateFetch); /* Come back to fetch */
} /* switch */
// After doing, wait for the next clock fall edge
wait();
} /* for */
} /* function */
// State driven process for managing signal assignment
// This is a method process
void DataPath::control_process() {
// If reset signal is up then CU must be resetted
if (this->rst.read()) {
// Reset
this->reset_signals(); /* Initializing signals */
} else {
// No Reset
// Switching on state
switch (this->cu_state.read()) {
case StateFetch: /* FETCH */
// Managing memory address and instruction fetch to place in IR
this->mem_ctr_memreadenable.write(logic_sgm_1); /* Enabling memory to be read */
this->mem_ctr_memwriteenable.write(logic_sgm_0); /* Disabling memory from being written */
std::cout << "Entering fetch, memread=" << this->mem_ctr_memreadenable.read() << " memwrite=" << this->mem_ctr_memreadenable.read() << std::endl;
// Here I read from memory and get the instruction with some code that you do not need to worry about because my problem occurs HERE ###
break;
case kCUStateDecode: /* DECODE */
// ...
break;
//...
//...
default: /* Unrecognized */
newpc = "00000000000000000000000000000000";
} /* state switch */
} /* rst if */
} /* function */
// Resetting signals
void DataPath::reset_signals() {
// Out signals
this->mem_ctr_memreadenable.write(logic_sgm_1);
this->mem_ctr_memwriteenable.write(logic_sgm_0);
}
As you can see we have a clock driven process that handles cpu transitions (changing state) and a state driven process that sets signals for cpu.
My problem is that when I arrive in ### I expect the instruction being released by memory (you cannot see the instructions but they are correct, the memory component is connected to datapath using in and out singals you can see in the hpp file).
Memory gets me "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" because mem_ctr_memreadenable and mem_ctr_memwriteenable are both set to '0'.
Memory module is written in order to be an instant component. It is written using a SC_METHOD whose sensitive is defined on input signals (read enable and write enable included). The memory component gets "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" when the mem_ctr_memreadenable signal is '0'.
Why is it '0'? I reset signals and set that signal to '1'. I do not understand why I keep having '0' for the read enable signal.
Can you help me?
Thankyou.
I'm no SystemC guru, but it looks like it might be a similar problem to a common VHDL problem of signals not updating until at least a delta-cycle has passed:
this->mem_ctr_memreadenable.write(logic_sgm_1); /* Enabling memory to be read */
this->mem_ctr_memwriteenable.write(logic_sgm_0); /* Disabling memory from being written */
My guess: No time passes between these two lines and this next line:
std::cout << "Entering fetch, memread=" << this->mem_ctr_memreadenable.read() << " memwrite=" << this->mem_ctr_memreadenable.read() << std::endl;
So the memory hasn't yet seen the read signal change. BTW, should one of the read() calls attached to mem_ctr_memwriteenable - the both seem to be on readenable?
If you:
wait(1, SC_NS);
between those two points, does it improve matters?
To get a zero time synchronization with the memory module you should use
wait(SC_ZERO_TIME); //wait one delta cycle
not to introduce an arbitrary consumtion of time in your timed simulation.
This also impose you upgrade your control_process to an SC_THREAD
I used to write apache modules in apache 1.3, but these days I am willing to pass to apache2. The module that I am writing at the moment has is own binary data, not a database, for performance purposes. I need to load this data in shared memory, so every child can access it without making his own copy, and it would be practical to load/create the binary data at startup, as I was used to do with apache 1.3. Problem is that I don't find an init event in apache2, in 1.3 in the module struct, immediatly after STANDARD_MODULE_STUFF you find a place for a /** module initializer */, in which you can put a function that will be executed early.
Body of the function I used to write is something like:
if ( getppid == 1 )
{
// Load global data here
// this is the parent process
void* data = loadGlobalData( someFilePath );
setGlobalData( config, data );
}
else
{
// this is the init of a child process
// do nothing
}
I am looking for a place in apache2 in where I can put a similar function.
Can you help?
Thanks
Benvenuto
Since you want the server to create a single shared memory segment to be used by all children, I would recommend initialising this in the post config hook (ap_hook_post_config). This is called once the configuration has been read, but before the children are spawned, so it should work well.
Since Apache 2.x loads DSO modules twice, ap_hook_post_config() is called twice during Apache startup.
The following code added to the ap_hook_post_config() will prevent the initialization of your module during the first call and continue only during the second call.
This is a hack, but a neat hack :)
void *data = NULL;
const char *key = "dummy_post_config";
// This code is used to prevent double initialization of the module during Apache startup
apr_pool_userdata_get(&data, key, s->process->pool);
if ( data == NULL ) {
apr_pool_userdata_set((const void *)1, key, apr_pool_cleanup_null, s->process->pool);
return OK;
}
You can read more about double dso module loads on the Apache wiki.
You can use a child_init hook to initialize a resource that will last longer then request or connection.
typedef struct {
apr_pool_t *pool;
apr_hash_t *hash;
} my_server_config;
static void my_child_init(apr_pool_t *p, server_rec *s)
{
my_server_config cfg = ap_get_module_config(s->module_config, &my_module);
/* Create sub-pool: ap_pool_create(&cfg->pool, p); */
/* Create hash: cfg->hash = ap_hash_make(cfg->pool); */
}
static void my_register_hooks(apr_pool_t *p)
{
ap_hook_child_init(my_child_init, NULL, NULL, APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA my_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* per-directory config creator */
NULL, /* dir config merger */
NULL, /* server config creator */
NULL, /* server config merger */
NULL, /* command table */
my_register_hooks, /* set up other request processing hooks */
};
Child init hook will be called before apache enters operational mode or before threads are created in threaded MPM. The pool passed into the my_child_init function should be process pool.
For better example you should download apache source code and check the modules/experimental/mod_example.c file.