Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re: error in marshalling #2537

Closed
vicuna opened this issue Jul 25, 2000 · 2 comments
Closed

Re: error in marshalling #2537

vicuna opened this issue Jul 25, 2000 · 2 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Jul 25, 2000

Original bug ID: 168
Reporter: administrator
Status: closed
Resolution: not a bug
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Hi,

Thank you for your message to the Caml mailing list.

However your message seems to be a bug report; hence I send it to the
relevant mailing list

caml-bugs@inria.fr

Thank again for your interest in Caml.

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/

Hi,

I'm currently programming a distributed application implementing
Hewitt's and Agha's Actors.

At some time, I try to send a 'behavior', that's to say a special
function. Therefore, I first marshal it, then I send it. But it fails
and an exception Invalid_argument is raised. I know the functions of
module Marshal don't work with bytecode-threads, so I use a trick given
by X. Leroy.

Here is what happens:

type address = { (* 4 fields, similar to IP *)
mutable cluster : int;
mutable machine : int;
mutable process : int;
mutable actor : int;
}

and actor = {
box : mailbox;
ego : address;
mutable self : behavior;
}

and behavior = actor -> unit

and mailbox = {
mb_new_ones : packet Queue.t;
mutable mb_new_max_size : int option;
mb_old_ones : packet Mutable_queue.t; (* resizable array by M.Mottl
*)
mutable mb_old_max_size : int option;
mutable mb_look_old_ones : bool;
mutable mb_accept_msg : packet -> bool;
mb_mutex : Mutex.t;
mb_cond : Condition.t;
}

and packet = packet_type * packet_arg

and packet_type =
| NOTIFY_SUICIDE (* ego -> NS )
... many constructors ...
| PERFORM_RUN (
PS -> PS *)
| MESSAGE of string

and packet_arg =
| PA_unit
... many constructors ...
| PA_addr_beh of address * behavior
| PA_msg_arg of argument

and argument (* abstract *)

The rewritten marshalling function :

let to_channel oc v =
Pervasives.output_string oc (Marshal.to_string v [Marshal.Closures])

The sending function:

let send_on cout from dest (pcktype, data) =
  Mutex.lock cout.mto_mutex;
  send_dest cout dest;
  send_pcktype cout pcktype;
  send_from cout from;
  send_data cout data;    (* the exception will be raise here *)
  Mutex.unlock cout.mto_mutex

The send_data function :

let send_data chan data =
  Marshalling.to_channel chan.mto_chan data;
  flush chan.mto_chan

Then when the program is executed, it encounters this instruction:

send_on cout ps_addr (upper_address addr) (PERFORM_RUN,
PA_addr_beh (addr, beh))

Here is what happens then:
Fatal error: uncaught exception Invalid_argument("output_value: object
value")

I tried to look at the C code in byterun/extern.c in the OCaml 3.00
distribution, but I didn't understand very much. I saw that the system
finds an Object_tag which I wonder where the system finds it :-)

Any comment or idea will be strongly appreciated ;-)

dc

--
David Chemouil [mailto:chemouil@enseeiht.fr] [mobile: 06 84 16 26 65]

Laboratoire d'informatique et de mathématiques appliquées (IRIT-INPT)

@vicuna
Copy link
Author

vicuna commented Jul 28, 2000

Comment author: administrator

At some time, I try to send a 'behavior', that's to say a special
function. Therefore, I first marshal it, then I send it. But it fails
and an exception Invalid_argument is raised. I know the functions of
module Marshal don't work with bytecode-threads, so I use a trick given
by X. Leroy.

Right. The Marshall module will be thread-safe in future releases.

Here is what happens:
Fatal error: uncaught exception Invalid_argument("output_value: object
value")
I tried to look at the C code in byterun/extern.c in the OCaml 3.00
distribution, but I didn't understand very much. I saw that the system
finds an Object_tag which I wonder where the system finds it :-)

Well, it means that the data structure you gave to the marshaller
contains an object somewhere (including in the closures of the
functions that you're marshalling). Maybe in the Mutable_queue.t type?
Also, it seems that your data may contain mutexes and conditions,
which you cannot marshal reliably.

Generally speaking, the OCaml marshaller works only for pure, passive
data structures: no functions, no objects, no stateful things like
file descriptors and mutexes. The Marshal.Closures flag allows
functions to be marshaled under some circumstances, but it's really a
hack that works only for very simple SPMD programming.

I agree this makes the marshaller insufficient for advanced
distributed programming -- the Join Calculus / JoeCaml people also
have problems with this. But there is no ideal solution known
currently.

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Jul 28, 2000

Comment author: administrator

Inherent limitations of the marshaler.

@vicuna vicuna closed this as completed Jul 28, 2000
@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant