You may also want to take a look at http://protozilla.mozdev.org, which implements 
generic
protocol handlers. The source code includes examples of "wrapped" channels.

Saravanan

Heribert Schuetz wrote:

> Hi,
>
> we are currently implementing a protocol handler (let's say for a schema
> "map") somewhat similar to the one for "resource" URIs. For an URI like
> "map:foo" the channel (a `mapChannel') looks up "foo" in some table,
> where it is mapped to, say, "http://bar.com/". So the mapChannel
> constructs an auxiliary channel for "http://bar.com/". This happens in
> mapChannel::Init(). Most of the other methods simply call the
> corresponding methods of the auxiliary channel.
>
> Exceptions:
>
> - mapChannel::AsyncOpen(...) calls AsyncOpen(...) of the auxiliary
>   channel, but it passes itself as the listener rather than the
>   "outside" listener received as an argument. (The outside listener is
>   remembered in a member variable of the mapChannel.) Thus listener
>   calls (OnStartRequest, OnStopRequest, OnDataAvailable) from the
>   auxiliary channel are sent to the mapChannel, which forwards these
>   calls to the outside listener, however passing itself rather than the
>   received channel (which would typically be the auxiliary channel).
>
> - mapChannel::GetURI() returns the original URI ("map:foo") rather than
>   asking the auxiliary channel for its URI ("http://bar.com/").
>
> The modification of AsyncOpen(...) and the implementation of the
> listener interface by mapChannel has essentially the purpose to force
> the outer listener to ask the mapChannel rather than the auxiliary
> channel for its URI.
>
> So far everything is quite standard and we think that we more or less
> understand it. It works. Now there is a somewhat more complex situation
> for which I would ask for your advice.
>
> Actually the mapping table is not readily available for lookup. We
> rather have a socket connection to some "map server". We can write the
> original URI ("map:foo" or just "foo") to that socket and tell the
> socket's input listener to perform some callback action when the
> translated URI arrives from the server.
>
> That is, we have only some sort of "asynchronous" access to the mapping
> table and we are not sure how to adapt the implementation of mapChannel
> to that.
>
> - One idea is to use threads and event queues to provide a synchronous
>   interface to the "mapping service" (i.e., a function call returning
>   the mapped URI rather than a callback).
>
>   However, this might be overkill. It might also block important threads
>   if not done properly. Furthermore, we would have to learn a lot about
>   threads and event queues. (Is there any up-to-date documentation
>   available?)
>
> - Another idea is to stick with the callback-style interface of the
>   mapping service: The mapChannel sends "foo" to the mapping service,
>   thereby registering a callback that will eventually create the
>   auxiliary channel.
>
>   The problem with this approach is that we do not know how to deal with
>   method calls to the mapChannel before the auxiliary channel is
>   available. So we cannot simply forward them to the auxiliary channel.
>   Well, for certain methods we can do something sensible, but still we
>   would like to simply forward most method calls in order to make our
>   layer as transparent as possible.
>
>   Fortunately, it looks like many channel methods are not invoked before
>   a channel has called OnStartRequest(...) at its listener. (After that
>   time we know that the auxiliary channel exists and we can forward
>   mapChannel method calls to it.) Can we rely on this? Is there some
>   (written or implicit) specification that tells when which channel
>   method may be legally invoked?
>
>   Furthermore we have no idea how to implement mapChannel::Open() with
>   this approach.
>
> Any hints are appreciated,
>
> Heribert.


Reply via email to