diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-08-25 14:32:38 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-08-25 23:05:05 +1000 |
commit | 4f8087cdb95c6036358a41398d73c3ad90c5755c (patch) | |
tree | d147d6fdd26535d578abeabe34136fc5c2f81b1b /pidl | |
parent | 634e06e465be7a8921cb95884ec427f48bf812da (diff) | |
download | samba-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
Diffstat (limited to 'pidl')
-rw-r--r-- | pidl/lib/Parse/Pidl/Samba4/Python.pm | 38 |
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($$$) |