1  /*
   2   * \brief  Connection to a service
   3   * \author Norman Feske
   4   * \date   2008-08-22
   5   */

   6  
   7  /*
   8   * Copyright (C) 2008-2013 Genode Labs GmbH
   9   *
  10   * This file is part of the Genode OS framework, which is distributed
  11   * under the terms of the GNU General Public License version 2.
  12   */

  13  
  14  #ifndef _INCLUDE__BASE__CONNECTION_H_
  15  #define _INCLUDE__BASE__CONNECTION_H_
  16  
  17  #include <base/env.h>
  18  #include <base/capability.h>
  19  
  20  namespace Genode { template <typename> class Connection; }
  21  
  22  
  23  /**
  24   * Representation of an open connection to a service
  25   */

  26  template <typename SESSION_TYPE>
  27  class Genode::Connection : public Noncopyable
  28  {
  29     public:
  30  
  31        enum On_destruction { CLOSE = false, KEEP_OPEN = true };

  32  
  33     private:
  34  
  35        /*
  36         * Because the argument string is used with the parent interface,
  37         * the message-buffer size of the parent-interface provides a
  38         * realistic upper bound for dimensioning the format- string
  39         * buffer.
  40         */

  41        enum { FORMAT_STRING_SIZE = Parent::Session_args::MAX_SIZE };

  42  
  43        Capability<SESSION_TYPE> _cap;
  44  
  45        On_destruction _on_destruction;
  46  
  47        Capability<SESSION_TYPE> _session(Affinity const &affinity,
  48                                          const char *format_args, va_list list)

  49        {
  50           char buf[FORMAT_STRING_SIZE];
  51  
  52           String_console sc(buf, FORMAT_STRING_SIZE);
  53           sc.vprintf(format_args, list);
  54  
  55           va_end(list);
  56  
  57           /* call parent interface with the resulting argument buffer */
  58           return env()->parent()->session<SESSION_TYPE>(buf, affinity);

  59        }

  60  
  61     public:
  62  
  63        /**
  64         * Constructor
  65         *
  66         * \param cap  session capability
  67         * \param od   session policy applied when destructing the connection
  68         *
  69         * The `op` argument defines whether the session should automatically
  70         * be closed by the destructor of the connection (CLOSE), or the
  71         * session should stay open (KEEP_OPEN). The latter is useful in
  72         * situations where the creator a connection merely passes the
  73         * session capability of the connection to another party but never
  74         * invokes any of the session`s RPC functions.
  75         */

  76        Connection(Capability<SESSION_TYPE> cap, On_destruction od = CLOSE):
  77           _cap(cap), _on_destruction(od)
 { }

  78  
  79        /**
  80         * Destructor
  81         */

  82        ~Connection()
  83        {
  84           if (_on_destruction == CLOSE)
  85              env()->parent()->close(_cap);

  86        }

  87  
  88        /**
  89         * Return session capability
  90         */

  91        Capability<SESSION_TYPE> cap() const { return _cap; }

  92  
  93        /**
  94         * Define session policy
  95         */

  96        void on_destruction(On_destruction od) { _on_destruction = od; }

  97  
  98        /**
  99         * Shortcut for env()->parent()->session()
 100         */

 101        Capability<SESSION_TYPE> session(const char *format_args, ...)
 102        {
 103           va_list list;
 104           va_start(list, format_args);
 105  
 106           return _session(Affinity(), format_args, list);

 107        }

 108  
 109        /**
 110         * Shortcut for env()->parent()->session()
 111         */

 112        Capability<SESSION_TYPE> session(Affinity const &affinity,
 113                                         char     const *format_args, ...)

 114        {
 115           va_list list;
 116           va_start(list, format_args);
 117  
 118           return _session(affinity, format_args, list);

 119        }

 120  }
;

 121  
 122  #endif /* _INCLUDE__BASE__CONNECTION_H_ */