summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-08-25 14:32:38 +1000
committerAndrew Tridgell <tridge@samba.org>2010-08-25 23:05:05 +1000
commit4f8087cdb95c6036358a41398d73c3ad90c5755c (patch)
treed147d6fdd26535d578abeabe34136fc5c2f81b1b
parent634e06e465be7a8921cb95884ec427f48bf812da (diff)
downloadsamba-4f8087cdb95c6036358a41398d73c3ad90c5755c.tar.gz
samba-4f8087cdb95c6036358a41398d73c3ad90c5755c.tar.bz2
samba-4f8087cdb95c6036358a41398d73c3ad90c5755c.zip
s4-python: reference substructures onto the parent structure
when a python object that is part of a parent structure is created, we should reference it on the parent structure. This ensures that when the child object goes out of scope that the parent structure is still valid
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Python.pm38
1 files changed, 23 insertions, 15 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 6adc60c554..eb39718bb5 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -158,7 +158,7 @@ sub FromPythonToUnionFunction($$$$$)
if ($e->{CASE} eq "default") { $has_default = 1; }
$self->indent;
if ($e->{NAME}) {
- $self->ConvertObjectFromPython({}, $mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;");
+ $self->ConvertObjectFromPython({}, $mem_ctx, undef, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;");
}
$self->pidl("break;");
$self->deindent;
@@ -209,14 +209,15 @@ sub PythonStruct($$$$$$)
$self->indent;
$self->pidl("$cname *object = ($cname *)py_talloc_get_ptr(py_obj);");
my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)";
+ my $mem_ref = "py_talloc_get_ptr(py_obj)";
my $l = $e->{LEVELS}[0];
my $nl = GetNextLevel($e, $l);
if ($l->{TYPE} eq "POINTER" and
not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and
not ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE}))) {
- $self->pidl("talloc_free($varname);");
+ $self->pidl("talloc_unlink(py_talloc_get_mem_ctx(py_obj), $varname);");
}
- $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;");
+ $self->ConvertObjectFromPython($env, $mem_ctx, $mem_ref, $e, "value", $varname, "return -1;");
$self->pidl("return 0;");
$self->deindent;
$self->pidl("}");
@@ -512,7 +513,7 @@ sub PythonFunctionPackIn($$$)
$self->pidl("r->in.$e->{NAME} = $val;");
}
} else {
- $self->ConvertObjectFromPython($env, "r", $e, "py_$e->{NAME}", "r->in.$e->{NAME}", $fail);
+ $self->ConvertObjectFromPython($env, "r", undef, $e, "py_$e->{NAME}", "r->in.$e->{NAME}", $fail);
}
}
$self->pidl("return true;");
@@ -876,7 +877,7 @@ sub ConvertObjectFromPythonData($$$$$$;$)
return;
}
$self->pidl("PY_CHECK_TYPE($ctype_name, $cvar, $fail);");
- $self->assign($target, "(".mapTypeName($ctype)." *)py_talloc_get_ptr($cvar)");
+ $self->assign($target, "talloc_reference($mem_ctx, (".mapTypeName($ctype)." *)py_talloc_get_ptr($cvar))");
return;
}
@@ -926,14 +927,14 @@ sub ConvertObjectFromPythonData($$$$$$;$)
}
-sub ConvertObjectFromPythonLevel($$$$$$$$)
+sub ConvertObjectFromPythonLevel($$$$$$$$$)
{
- my ($self, $env, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_;
+ my ($self, $env, $mem_ctx, $mem_ref, $py_var, $e, $l, $var_name, $fail) = @_;
my $nl = GetNextLevel($e, $l);
if ($l->{TYPE} eq "POINTER") {
if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $mem_ref, $py_var, $e, $nl, $var_name, $fail);
return;
}
if ($l->{POINTER_TYPE} ne "ref") {
@@ -944,8 +945,10 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
$self->pidl("} else {");
$self->indent;
}
- $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, get_value_of($var_name), $fail);
+ # if we want to handle more than one level of pointer in python interfaces
+ # then this is where we would need to allocate it
+ $self->pidl("$var_name = NULL;");
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $mem_ref, $py_var, $e, $nl, get_value_of($var_name), $fail);
if ($l->{POINTER_TYPE} ne "ref") {
$self->deindent;
$self->pidl("}");
@@ -968,10 +971,15 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
$self->pidl("int $counter;");
if (ArrayDynamicallyAllocated($e, $l)) {
$self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_Size($py_var));");
+ $self->pidl("if (!$var_name) { $fail; }");
+ $self->pidl("talloc_set_name_const($var_name, \"ARRAY: $var_name\");");
+ if ($mem_ref) {
+ $self->pidl("if (!talloc_reference($mem_ref, $var_name)) { $fail }");
+ }
}
$self->pidl("for ($counter = 0; $counter < PyList_Size($py_var); $counter++) {");
$self->indent;
- $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail);
+ $self->ConvertObjectFromPythonLevel($env, $var_name, undef, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail);
$self->deindent;
$self->pidl("}");
$self->deindent;
@@ -996,17 +1004,17 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
$self->deindent;
$self->pidl("}");
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, undef, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
} else {
fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
}
}
-sub ConvertObjectFromPython($$$$$$$)
+sub ConvertObjectFromPython($$$$$$$$)
{
- my ($self, $env, $mem_ctx, $ctype, $cvar, $target, $fail) = @_;
+ my ($self, $env, $mem_ctx, $mem_ref, $ctype, $cvar, $target, $fail) = @_;
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail);
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $mem_ref, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail);
}
sub ConvertScalarToPython($$$)