From 4f8087cdb95c6036358a41398d73c3ad90c5755c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 25 Aug 2010 14:32:38 +1000 Subject: [PATCH] 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 --- pidl/lib/Parse/Pidl/Samba4/Python.pm | 38 +++++++++++++++++----------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 6adc60c5541f..eb39718bb5c1 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($$$) -- 2.34.1