dom/plugins/ipc/hangui/MiniShmBase.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/plugins/ipc/hangui/MiniShmBase.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,334 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef mozilla_plugins_MiniShmBase_h
    1.11 +#define mozilla_plugins_MiniShmBase_h
    1.12 +
    1.13 +#include "base/basictypes.h"
    1.14 +
    1.15 +#include "nsDebug.h"
    1.16 +
    1.17 +#include <windows.h>
    1.18 +
    1.19 +namespace mozilla {
    1.20 +namespace plugins {
    1.21 +
    1.22 +/**
    1.23 + * This class is used to provide RAII semantics for mapped views.
    1.24 + * @see ScopedHandle
    1.25 + */
    1.26 +class ScopedMappedFileView
    1.27 +{
    1.28 +public:
    1.29 +  explicit
    1.30 +  ScopedMappedFileView(LPVOID aView)
    1.31 +    : mView(aView)
    1.32 +  {
    1.33 +  }
    1.34 +
    1.35 +  ~ScopedMappedFileView()
    1.36 +  {
    1.37 +    Close();
    1.38 +  }
    1.39 +
    1.40 +  void
    1.41 +  Close()
    1.42 +  {
    1.43 +    if (mView) {
    1.44 +      ::UnmapViewOfFile(mView);
    1.45 +      mView = nullptr;
    1.46 +    }
    1.47 +  }
    1.48 +
    1.49 +  void
    1.50 +  Set(LPVOID aView)
    1.51 +  {
    1.52 +    Close();
    1.53 +    mView = aView;
    1.54 +  }
    1.55 +
    1.56 +  LPVOID
    1.57 +  Get() const
    1.58 +  {
    1.59 +    return mView;
    1.60 +  }
    1.61 +
    1.62 +  LPVOID
    1.63 +  Take()
    1.64 +  {
    1.65 +    LPVOID result = mView;
    1.66 +    mView = nullptr;
    1.67 +    return result;
    1.68 +  }
    1.69 +
    1.70 +  operator LPVOID()
    1.71 +  {
    1.72 +    return mView;
    1.73 +  }
    1.74 +
    1.75 +  bool
    1.76 +  IsValid() const
    1.77 +  {
    1.78 +    return (mView);
    1.79 +  }
    1.80 +
    1.81 +private:
    1.82 +  DISALLOW_COPY_AND_ASSIGN(ScopedMappedFileView);
    1.83 +
    1.84 +  LPVOID mView;
    1.85 +};
    1.86 +
    1.87 +class MiniShmBase;
    1.88 +
    1.89 +class MiniShmObserver
    1.90 +{
    1.91 +public:
    1.92 +  /**
    1.93 +   * This function is called whenever there is a new shared memory request.
    1.94 +   * @param aMiniShmObj MiniShmBase object that may be used to read and 
    1.95 +   *                    write from shared memory.
    1.96 +   */
    1.97 +  virtual void OnMiniShmEvent(MiniShmBase *aMiniShmObj) = 0;
    1.98 +  /**
    1.99 +   * This function is called once when a MiniShmParent and a MiniShmChild
   1.100 +   * object have successfully negotiated a connection.
   1.101 +   *
   1.102 +   * @param aMiniShmObj MiniShmBase object that may be used to read and 
   1.103 +   *                    write from shared memory.
   1.104 +   */
   1.105 +  virtual void OnMiniShmConnect(MiniShmBase *aMiniShmObj) { }
   1.106 +};
   1.107 +
   1.108 +/**
   1.109 + * Base class for MiniShm connections. This class defines the common 
   1.110 + * interfaces and code between parent and child.
   1.111 + */
   1.112 +class MiniShmBase
   1.113 +{
   1.114 +public:
   1.115 +  /**
   1.116 +   * Obtains a writable pointer into shared memory of type T.
   1.117 +   * typename T must be plain-old-data and contain an unsigned integral 
   1.118 +   * member T::identifier that uniquely identifies T with respect to 
   1.119 +   * other types used by the protocol being implemented.
   1.120 +   *
   1.121 +   * @param aPtr Pointer to receive the shared memory address.
   1.122 +   *             This value is set if and only if the function 
   1.123 +   *             succeeded.
   1.124 +   * @return NS_OK if and only if aPtr was successfully obtained.
   1.125 +   *         NS_ERROR_ILLEGAL_VALUE if type T is not valid for MiniShm.
   1.126 +   *         NS_ERROR_NOT_INITIALIZED if there is no valid MiniShm connection.
   1.127 +   *         NS_ERROR_NOT_AVAILABLE if the memory is not safe to write.
   1.128 +   */
   1.129 +  template<typename T> nsresult
   1.130 +  GetWritePtr(T*& aPtr)
   1.131 +  {
   1.132 +    if (!mWriteHeader || !mGuard) {
   1.133 +      return NS_ERROR_NOT_INITIALIZED;
   1.134 +    }
   1.135 +    if (sizeof(T) > mPayloadMaxLen ||
   1.136 +        T::identifier <= RESERVED_CODE_LAST) {
   1.137 +      return NS_ERROR_ILLEGAL_VALUE;
   1.138 +    }
   1.139 +    if (::WaitForSingleObject(mGuard, mTimeout) != WAIT_OBJECT_0) {
   1.140 +      return NS_ERROR_NOT_AVAILABLE;
   1.141 +    }
   1.142 +    mWriteHeader->mId = T::identifier;
   1.143 +    mWriteHeader->mPayloadLen = sizeof(T);
   1.144 +    aPtr = reinterpret_cast<T*>(mWriteHeader + 1);
   1.145 +    return NS_OK;
   1.146 +  }
   1.147 +
   1.148 +  /**
   1.149 +   * Obtains a readable pointer into shared memory of type T.
   1.150 +   * typename T must be plain-old-data and contain an unsigned integral 
   1.151 +   * member T::identifier that uniquely identifies T with respect to 
   1.152 +   * other types used by the protocol being implemented.
   1.153 +   *
   1.154 +   * @param aPtr Pointer to receive the shared memory address.
   1.155 +   *             This value is set if and only if the function 
   1.156 +   *             succeeded.
   1.157 +   * @return NS_OK if and only if aPtr was successfully obtained.
   1.158 +   *         NS_ERROR_ILLEGAL_VALUE if type T is not valid for MiniShm or if
   1.159 +   *                                type T does not match the type of the data
   1.160 +   *                                stored in shared memory.
   1.161 +   *         NS_ERROR_NOT_INITIALIZED if there is no valid MiniShm connection.
   1.162 +   */
   1.163 +  template<typename T> nsresult
   1.164 +  GetReadPtr(const T*& aPtr)
   1.165 +  {
   1.166 +    if (!mReadHeader) {
   1.167 +      return NS_ERROR_NOT_INITIALIZED;
   1.168 +    }
   1.169 +    if (mReadHeader->mId != T::identifier ||
   1.170 +        sizeof(T) != mReadHeader->mPayloadLen) {
   1.171 +      return NS_ERROR_ILLEGAL_VALUE;
   1.172 +    }
   1.173 +    aPtr = reinterpret_cast<const T*>(mReadHeader + 1);
   1.174 +    return NS_OK;
   1.175 +  }
   1.176 +
   1.177 +  /**
   1.178 +   * Fires the peer's event causing its request handler to execute.
   1.179 +   *
   1.180 +   * @return Should return NS_OK if the send was successful.
   1.181 +   */
   1.182 +  virtual nsresult
   1.183 +  Send() = 0;
   1.184 +
   1.185 +protected:
   1.186 +  /**
   1.187 +   * MiniShm reserves some identifier codes for its own use. Any 
   1.188 +   * identifiers used by MiniShm protocol implementations must be 
   1.189 +   * greater than RESERVED_CODE_LAST.
   1.190 +   */
   1.191 +  enum ReservedCodes
   1.192 +  {
   1.193 +    RESERVED_CODE_INIT = 0,
   1.194 +    RESERVED_CODE_INIT_COMPLETE = 1,
   1.195 +    RESERVED_CODE_LAST = RESERVED_CODE_INIT_COMPLETE
   1.196 +  };
   1.197 +
   1.198 +  struct MiniShmHeader
   1.199 +  {
   1.200 +    unsigned int  mId;
   1.201 +    unsigned int  mPayloadLen;
   1.202 +  };
   1.203 +
   1.204 +  struct MiniShmInit
   1.205 +  {
   1.206 +    enum identifier_t
   1.207 +    {
   1.208 +      identifier = RESERVED_CODE_INIT
   1.209 +    };
   1.210 +    HANDLE    mParentEvent;
   1.211 +    HANDLE    mParentGuard;
   1.212 +    HANDLE    mChildEvent;
   1.213 +    HANDLE    mChildGuard;
   1.214 +  };
   1.215 +
   1.216 +  struct MiniShmInitComplete
   1.217 +  {
   1.218 +    enum identifier_t
   1.219 +    {
   1.220 +      identifier = RESERVED_CODE_INIT_COMPLETE
   1.221 +    };
   1.222 +    bool      mSucceeded;
   1.223 +  };
   1.224 +
   1.225 +  MiniShmBase()
   1.226 +    : mObserver(nullptr),
   1.227 +      mWriteHeader(nullptr),
   1.228 +      mReadHeader(nullptr),
   1.229 +      mPayloadMaxLen(0),
   1.230 +      mGuard(nullptr),
   1.231 +      mTimeout(INFINITE)
   1.232 +  {
   1.233 +  }
   1.234 +  virtual ~MiniShmBase()
   1.235 +  { }
   1.236 +
   1.237 +  virtual void
   1.238 +  OnEvent()
   1.239 +  {
   1.240 +    if (mObserver) {
   1.241 +      mObserver->OnMiniShmEvent(this);
   1.242 +    }
   1.243 +  }
   1.244 +
   1.245 +  virtual void
   1.246 +  OnConnect()
   1.247 +  {
   1.248 +    if (mObserver) {
   1.249 +      mObserver->OnMiniShmConnect(this);
   1.250 +    }
   1.251 +  }
   1.252 +
   1.253 +  nsresult
   1.254 +  SetView(LPVOID aView, const unsigned int aSize, bool aIsChild)
   1.255 +  {
   1.256 +    if (!aView || aSize <= 2 * sizeof(MiniShmHeader)) {
   1.257 +      return NS_ERROR_ILLEGAL_VALUE;
   1.258 +    }
   1.259 +    // Divide the region into halves for parent and child
   1.260 +    if (aIsChild) {
   1.261 +      mReadHeader = static_cast<MiniShmHeader*>(aView);
   1.262 +      mWriteHeader = reinterpret_cast<MiniShmHeader*>(static_cast<char*>(aView)
   1.263 +                                                      + aSize / 2U);
   1.264 +    } else {
   1.265 +      mWriteHeader = static_cast<MiniShmHeader*>(aView);
   1.266 +      mReadHeader = reinterpret_cast<MiniShmHeader*>(static_cast<char*>(aView)
   1.267 +                                                     + aSize / 2U);
   1.268 +    }
   1.269 +    mPayloadMaxLen = aSize / 2U - sizeof(MiniShmHeader);
   1.270 +    return NS_OK;
   1.271 +  }
   1.272 +
   1.273 +  nsresult
   1.274 +  SetGuard(HANDLE aGuard, DWORD aTimeout)
   1.275 +  {
   1.276 +    if (!aGuard || !aTimeout) {
   1.277 +      return NS_ERROR_ILLEGAL_VALUE;
   1.278 +    }
   1.279 +    mGuard = aGuard;
   1.280 +    mTimeout = aTimeout;
   1.281 +    return NS_OK;
   1.282 +  }
   1.283 +
   1.284 +  inline void
   1.285 +  SetObserver(MiniShmObserver *aObserver) { mObserver = aObserver; }
   1.286 +
   1.287 +  /**
   1.288 +   * Obtains a writable pointer into shared memory of type T. This version 
   1.289 +   * differs from GetWritePtr in that it allows typename T to be one of 
   1.290 +   * the private data structures declared in MiniShmBase.
   1.291 +   *
   1.292 +   * @param aPtr Pointer to receive the shared memory address.
   1.293 +   *             This value is set if and only if the function 
   1.294 +   *             succeeded.
   1.295 +   * @return NS_OK if and only if aPtr was successfully obtained.
   1.296 +   *         NS_ERROR_ILLEGAL_VALUE if type T not an internal MiniShm struct.
   1.297 +   *         NS_ERROR_NOT_INITIALIZED if there is no valid MiniShm connection.
   1.298 +   */
   1.299 +  template<typename T> nsresult
   1.300 +  GetWritePtrInternal(T*& aPtr)
   1.301 +  {
   1.302 +    if (!mWriteHeader) {
   1.303 +      return NS_ERROR_NOT_INITIALIZED;
   1.304 +    }
   1.305 +    if (sizeof(T) > mPayloadMaxLen ||
   1.306 +        T::identifier > RESERVED_CODE_LAST) {
   1.307 +      return NS_ERROR_ILLEGAL_VALUE;
   1.308 +    }
   1.309 +    mWriteHeader->mId = T::identifier;
   1.310 +    mWriteHeader->mPayloadLen = sizeof(T);
   1.311 +    aPtr = reinterpret_cast<T*>(mWriteHeader + 1);
   1.312 +    return NS_OK;
   1.313 +  }
   1.314 +
   1.315 +  static VOID CALLBACK
   1.316 +  SOnEvent(PVOID aContext, BOOLEAN aIsTimer)
   1.317 +  {
   1.318 +    MiniShmBase* object = static_cast<MiniShmBase*>(aContext);
   1.319 +    object->OnEvent();
   1.320 +  }
   1.321 +
   1.322 +private:
   1.323 +  MiniShmObserver*  mObserver;
   1.324 +  MiniShmHeader*    mWriteHeader;
   1.325 +  MiniShmHeader*    mReadHeader;
   1.326 +  unsigned int      mPayloadMaxLen;
   1.327 +  HANDLE            mGuard;
   1.328 +  DWORD             mTimeout;
   1.329 +
   1.330 +  DISALLOW_COPY_AND_ASSIGN(MiniShmBase);
   1.331 +};
   1.332 +
   1.333 +} // namespace plugins
   1.334 +} // namespace mozilla
   1.335 +
   1.336 +#endif // mozilla_plugins_MiniShmBase_h
   1.337 +

mercurial