Add logic to automatically unload module on exit; Several patches from Mike Smith

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5528 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2013-01-17 14:43:55 +00:00
parent 828c1c65c7
commit 956bded9c1
12 changed files with 194 additions and 65 deletions
+4
View File
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_BINFMT_EXEPATH),y)
BINFMT_CSRCS += binfmt_exepath.c
endif
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
BINFMT_CSRCS += binfmt_schedunload.c
endif
# Symbol table source files
BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c
+67 -2
View File
@@ -74,7 +74,9 @@
*
* Description:
* This is a convenience function that wraps load_ and exec_module into
* one call.
* one call. If CONFIG_SCHED_ONEXIT is also defined, this function will
* automatically call schedule_unload() to unload the module when task
* exits.
*
* Input Parameter:
* filename - Fulll path to the binary to be loaded
@@ -84,7 +86,7 @@
*
* Returned Value:
* This is an end-user function, so it follows the normal convention:
* Returns the PID of the exec'ed module. On failure, it.returns
* It returns the PID of the exec'ed module. On failure, it returns
* -1 (ERROR) and sets errno appropriately.
*
****************************************************************************/
@@ -92,6 +94,66 @@
int exec(FAR const char *filename, FAR const char **argv,
FAR const struct symtab_s *exports, int nexports)
{
#ifdef CONFIG_SCHED_ONEXIT
FAR struct binary_s *bin;
int errorcode;
int ret;
/* Allocate the load information */
bin = (FAR struct binary_s *)kzalloc(sizeof(struct binary_s));
if (!bin)
{
set_errno(ENOMEM);
return ERROR;
}
/* Load the module into memory */
bin->filename = filename;
bin->exports = exports;
bin->nexports = nexports;
ret = load_module(bin);
if (ret < 0)
{
bdbg("ERROR: Failed to load program '%s'\n", filename);
kfree(bin);
return ERROR;
}
/* Disable pre-emption so that the executed module does
* not return until we get a chance to connect the on_exit
* handler.
*/
sched_lock();
/* Then start the module */
ret = exec_module(bin);
if (ret < 0)
{
bdbg("ERROR: Failed to execute program '%s'\n", filename);
sched_unlock();
unload_module(bin);
kfree(bin);
return ERROR;
}
/* Set up to unload the module (and free the binary_s structure)
* when the task exists.
*/
ret = schedul_unload(ret, bin);
if (ret < 0)
{
bdbg("ERROR: Failed to schedul unload '%s'\n", filename);
}
sched_unlock();
return ret;
#else
struct binary_s bin;
int ret;
@@ -119,7 +181,10 @@ int exec(FAR const char *filename, FAR const char **argv,
return ERROR;
}
/* TODO: How does the module get unloaded in this case? */
return ret;
#endif
}
#endif /* CONFIG_BINFMT_DISABLE */
+5 -3
View File
@@ -89,6 +89,7 @@ static struct binfmt_s g_builtin_binfmt =
static int builtin_loadbinary(struct binary_s *binp)
{
FAR const char *filename;
FAR const struct builtin_s *b;
int fd;
int index;
int ret;
@@ -134,9 +135,10 @@ static int builtin_loadbinary(struct binary_s *binp)
* the priority. That is a bug and needs to be fixed.
*/
binp->entrypt = g_builtins[index].main;
binp->stacksize = g_builtins[index].stacksize;
binp->priority = g_builtins[index].priority;
b = builtin_for_index(index);
binp->entrypt = b->main;
binp->stacksize = b->stacksize;
binp->priority = b->priority;
return OK;
}
+9 -5
View File
@@ -83,10 +83,14 @@
FAR const char *builtin_getname(int index)
{
if (index < 0 || index >= number_builtins())
{
return NULL;
}
struct builtin_s *b;
return g_builtins[index].name;
b = builtin_for_index(index);
if (b != NULL)
{
return b->name;
}
return NULL;
}
+4 -3
View File
@@ -80,18 +80,19 @@
* Name: builtin_isavail
*
* Description:
* Return the index into the table of applications for the applicaiton with
* Return the index into the table of applications for the application with
* the name 'appname'.
*
****************************************************************************/
int builtin_isavail(FAR const char *appname)
{
FAR const char *n;
int i;
for (i = 0; g_builtins[i].name; i++)
for (i = 0; n = builtin_getname(i); i++)
{
if (!strncmp(g_builtins[i].name, appname, NAME_MAX))
if (!strncmp(n, appname, NAME_MAX))
{
return i;
}