// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: morlovich@google.com (Maksim Orlovich)

#ifndef PAGESPEED_KERNEL_BASE_ABSTRACT_SHARED_MEM_H_
#define PAGESPEED_KERNEL_BASE_ABSTRACT_SHARED_MEM_H_

#include <cstddef>
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/string.h"

namespace net_instaweb {

class AbstractMutex;
class MessageHandler;

// This represents a region of memory shared between between multiple processes
// that may contain mutexes.
class AbstractSharedMemSegment {
 public:
  AbstractSharedMemSegment() {}

  // Destroying the segment object detaches from it, making all pointers into it
  // invalid.
  virtual ~AbstractSharedMemSegment();

  // Returns the base address of the segment. Note that there is no guarantee
  // that this address will be the same for other processes attached to the
  // same segment.
  virtual volatile char* Base() = 0;

  // Returns the number of bytes a mutex inside shared memory takes.
  virtual size_t SharedMutexSize() const = 0;

  // To use a mutex in shared memory, you first need to dedicate some
  // [offset, offset + SharedMutexSize()) chunk of memory to it. Then,
  // exactly one process must call InitializeSharedMutex(offset), and
  // all users must call AttachToSharedMutex(offset) afterwards.
  //
  // InitializeSharedMutex returns whether it succeeded or not.
  // AttachToSharedMutex returns a fresh object, giving ownership
  // to the caller. The object returned is outside shared memory,
  // and acts a helper for referring to the shared state.
  virtual bool InitializeSharedMutex(size_t offset,
                                     MessageHandler* handler) = 0;
  virtual AbstractMutex* AttachToSharedMutex(size_t offset) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(AbstractSharedMemSegment);
};

// Interface for creating and attaching to named shared memory segments.
// The expectation is that whichever implementation is used at runtime
// will be able to handle the combination of threads & processes used by
// the hosting environment.
//
// The basic flow here is as follows:
//
//            Single process/thread startup stage:
//            CreateSegment
//            InitializeSharedMutex -----+
//           /                           |
//          /                            |
//    process/thread:                   process/thread:
//    AttachToSegment                   AttachToSegment
//    AttachToSharedMutex               AttachToSharedMutex
//       |                                     |
//       |                                     |
//       |------------------------------------/
//       |
//    single process/thread cleanup stage:
//    DestroySegment
//
class AbstractSharedMem {
 public:
  AbstractSharedMem() {}
  virtual ~AbstractSharedMem();

  // Size of mutexes inside shared memory segments.
  virtual size_t SharedMutexSize() const = 0;

  // This should be called upon main process/thread initialization to create
  // a shared memory segment that will be accessed by other processes/threads
  // as identified by a unique name (via AttachToSegment). It will remove
  // any previous segment with the same name. The memory will be zeroed out.
  //
  // May return NULL on failure.
  virtual AbstractSharedMemSegment* CreateSegment(
      const GoogleString& name, size_t size, MessageHandler* handler) = 0;

  // Attaches to an existing segment, which must have been created already.
  // May return NULL on failure
  virtual AbstractSharedMemSegment* AttachToSegment(
      const GoogleString& name, size_t size, MessageHandler* handler) = 0;

  // Cleans up the segment with given name. You should call this after there is
  // no longer any need for AttachToSegment to succeed.
  virtual void DestroySegment(const GoogleString& name,
                              MessageHandler* handler) = 0;

  // Implementors such as NullSharedMem that don't actually support shared
  // memory operations should return true.  All real implementations should
  // leave this as false.
  virtual bool IsDummy() { return false; }

 private:
  DISALLOW_COPY_AND_ASSIGN(AbstractSharedMem);
};

}  // namespace net_instaweb

#endif  // PAGESPEED_KERNEL_BASE_ABSTRACT_SHARED_MEM_H_
