text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ComponentesTela.java
 *
 * Created on Mar 16, 2009, 1:13:05 PM
 */

package com.jdf.swing.helper;

import com.jdf.database.bean.Aluno;
import com.jdf.swing.iface.IconPackBase64;
import com.jdf.util.Propriedades;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPopupMenu;

/**
 *
 * @author rafael-lossurdo
 */
public class ComponentesTela extends javax.swing.JFrame {

    /** Creates new form ComponentesTela */
    public ComponentesTela() {
        initComponents();

        // formata frame principal
        JFrameHelper jfh = new JFrameHelper(this);
        jfh.setBigSize();
        jfh.setIcon(IconPackBase64.BOMB);
        jfh.setTitle(Propriedades.getInstance().get("sistema.titulo"));
        jfh.centerFrame();

        // formata botões
        JButtonHelper jbh1 = new JButtonHelper(btnVisualizaCombo);
        jbh1.setIcon(IconPackBase64.BUG);
        JButtonHelper jbh2 = new JButtonHelper(btnVisualizaListSimples);
        jbh2.setIcon(IconPackBase64.CART);

        // lista usada para listagens
        List<Aluno> alunos = new ArrayList<Aluno>();
        alunos.add(new Aluno(1,"Rafael Lossurdo"));
        alunos.add(new Aluno(2,"Queisi Oliveira"));
        alunos.add(new Aluno(3,"João da Silva"));
        List<Aluno> alunos2 = new ArrayList<Aluno>();
        alunos2.add(new Aluno(4,"Ana Maria"));
        alunos2.add(new Aluno(2,"Carlos Eduardo"));
        alunos2.add(new Aluno(5,"Giovanna da Silva"));

        // seta combo box
        jc = new JComboBoxHelper(comboBox);
        jc.setModel(alunos);

        // seta listbox simples
        jlh = new JListHelper(listUnico);
        jlh.setModel(alunos);

        // seta listbox complexo n:n
        JListHelper jlhComplexo = new JListHelper(listEsq, listDir, btnTodosDir, btnTodosEsq, btnDir, btnEsq);
        jlhComplexo.setModelLeft(alunos);
        jlhComplexo.setModelRight(alunos2);
        jlhComplexo.applyListeners();

        // modifica ícone dos botões n:n
        new JButtonHelper(btnTodosDir).setIcon(IconPackBase64.ARROW_TURN_RIGHT);
        new JButtonHelper(btnTodosEsq).setIcon(IconPackBase64.ARROW_TURN_LEFT);
        new JButtonHelper(btnDir).setIcon(IconPackBase64.ARROW_RIGHT);
        new JButtonHelper(btnEsq).setIcon(IconPackBase64.ARROW_LEFT);

        // link para browser
        JLabelHelper lh = new JLabelHelper(jLabel1);
        try {
			lh.transformToURLLink(new URI("http://www.terra.com.br"), JLabelHelper.DEFAULT_TOOLTIP);
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}

		// popup menu
		JPopupMenuHelper pp = new JPopupMenuHelper(new JPopupMenu("Meu Menu"), this);
		pp.addMenu("Teste A", 'A').
			addItem(null, null, "AAA", IconPackBase64.BASKET).
			addItem(null, null, "BBB");
		pp.addSeparator();
		pp.addMenu("Teste B", 'B').
			addItem(null, null, "CCC").
			addItem(null, null, "CCC").
			addItem(null, null, "CCC").
			addSeparator().
			addItem(null, null, "DDD");
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        comboBox = new javax.swing.JComboBox();
        btnVisualizaCombo = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        listUnico = new javax.swing.JList();
        jLabel3 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        listEsq = new javax.swing.JList();
        btnTodosDir = new javax.swing.JButton();
        btnDir = new javax.swing.JButton();
        btnEsq = new javax.swing.JButton();
        btnTodosEsq = new javax.swing.JButton();
        jScrollPane3 = new javax.swing.JScrollPane();
        listDir = new javax.swing.JList();
        btnVisualizaListSimples = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("Combo box");

        comboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        btnVisualizaCombo.setText("Visualizar Objeto Selecionado");
        btnVisualizaCombo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnVisualizaComboActionPerformed(evt);
            }
        });

        jLabel2.setText("List box");

        listUnico.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane1.setViewportView(listUnico);

        jLabel3.setText("List box N:N");

        listEsq.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane2.setViewportView(listEsq);

        btnTodosDir.setText("Todos");

        btnDir.setText("Mover");

        btnEsq.setText("Mover");

        btnTodosEsq.setText("Todos");

        listDir.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane3.setViewportView(listDir);

        btnVisualizaListSimples.setText("Visualizar Objeto Selecionado");
        btnVisualizaListSimples.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnVisualizaListSimplesActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 311, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnVisualizaListSimples))
                    .addComponent(jLabel1)
                    .addComponent(btnVisualizaCombo)
                    .addComponent(comboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 117, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 122, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(btnTodosDir, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(btnDir, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(btnEsq, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(btnTodosEsq, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 122, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(69, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(comboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnVisualizaCombo)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(btnVisualizaListSimples))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addComponent(btnTodosDir)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(btnDir)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(btnEsq)
                                .addGap(18, 18, 18)
                                .addComponent(btnTodosEsq))))
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(35, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnVisualizaComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnVisualizaComboActionPerformed
        JOptionPaneHelper.warning(jc.getSelectedObject().toString());
    }//GEN-LAST:event_btnVisualizaComboActionPerformed

    private void btnVisualizaListSimplesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnVisualizaListSimplesActionPerformed
        JOptionPaneHelper.warning(jlh.getSelectedObject().toString());
    }//GEN-LAST:event_btnVisualizaListSimplesActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ComponentesTela().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnDir;
    private javax.swing.JButton btnEsq;
    private javax.swing.JButton btnTodosDir;
    private javax.swing.JButton btnTodosEsq;
    private javax.swing.JButton btnVisualizaCombo;
    private javax.swing.JButton btnVisualizaListSimples;
    private javax.swing.JComboBox comboBox;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JList listDir;
    private javax.swing.JList listEsq;
    private javax.swing.JList listUnico;
    // End of variables declaration//GEN-END:variables
	private JComboBoxHelper jc;
	private JListHelper jlh;

}


text:
require 'test_helper'

class LabelOwnerTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end

redpajama_set_name: RedPajamaGithub


text:
var get = Ember.get;

/**

  WARNING: This interface is likely to change in order to accomodate https://github.com/emberjs/rfcs/pull/4

  ## Using BuildURLMixin

  To use url building, include the mixin when extending an adapter, and call `buildURL` where needed.
  The default behaviour is designed for RESTAdapter.

  ### Example

  ```javascript
  export default DS.Adapter.extend(BuildURLMixin, {
    find: function(store, type, id, snapshot) {
      var url = this.buildURL(type.modelName, id, snapshot, 'find');
      return this.ajax(url, 'GET');
    }
  });
  ```

  ### Attributes

  The `host` and `namespace` attributes will be used if defined, and are optional.

  @class BuildURLMixin
  @namespace DS
*/
export default Ember.Mixin.create({
  /**
    Builds a URL for a given type and optional ID.

    By default, it pluralizes the type's name (for example, 'post'
    becomes 'posts' and 'person' becomes 'people'). To override the
    pluralization see [pathForType](#method_pathForType).

    If an ID is specified, it adds the ID to the path generated
    for the type, separated by a `/`.

    When called by RESTAdapter.findMany() the `id` and `snapshot` parameters
    will be arrays of ids and snapshots.

    @method buildURL
    @param {String} modelName
    @param {String|Array|Object} id single id or array of ids or query
    @param {DS.Snapshot|Array} snapshot single snapshot or array of snapshots
    @param {String} requestType
    @param {Object} query object of query parameters to send for findQuery requests.
    @return {String} url
  */
  buildURL: function(modelName, id, snapshot, requestType, query) {
    switch (requestType) {
      case 'find':
        return this.urlForFind(id, modelName, snapshot);
      case 'findAll':
        return this.urlForFindAll(modelName);
      case 'findQuery':
        return this.urlForFindQuery(query, modelName);
      case 'findMany':
        return this.urlForFindMany(id, modelName, snapshot);
      case 'findHasMany':
        return this.urlForFindHasMany(id, modelName);
      case 'findBelongsTo':
        return this.urlForFindBelongsTo(id, modelName);
      case 'createRecord':
        return this.urlForCreateRecord(modelName, snapshot);
      case 'updateRecord':
        return this.urlForUpdateRecord(id, modelName, snapshot);
      case 'deleteRecord':
        return this.urlForDeleteRecord(id, modelName, snapshot);
      default:
        return this._buildURL(modelName, id);
    }
  },

  /**
    @method _buildURL
    @private
    @param {String} modelName
    @param {String} id
    @return {String} url
  */
  _buildURL: function(modelName, id) {
    var url = [];
    var host = get(this, 'host');
    var prefix = this.urlPrefix();
    var path;

    if (modelName) {
      path = this.pathForType(modelName);
      if (path) { url.push(path); }
    }

    if (id) { url.push(encodeURIComponent(id)); }
    if (prefix) { url.unshift(prefix); }

    url = url.join('/');
    if (!host && url && url.charAt(0) !== '/') {
      url = '/' + url;
    }

    return url;
  },

  /**
   * @method urlForFind
   * @param {String} id
   * @param {String} modelName
   * @param {DS.Snapshot} snapshot
   * @return {String} url
   */
  urlForFind: function(id, modelName, snapshot) {
    return this._buildURL(modelName, id);
  },

  /**
   * @method urlForFindAll
   * @param {String} modelName
   * @return {String} url
   */
  urlForFindAll: function(modelName) {
    return this._buildURL(modelName);
  },

  /**
   * @method urlForFindQuery
   * @param {Object} query
   * @param {String} modelName
   * @return {String} url
   */
  urlForFindQuery: function(query, modelName) {
    return this._buildURL(modelName);
  },

  /**
   * @method urlForFindMany
   * @param {Array} ids
   * @param {String} type
   * @param {Array} snapshots
   * @return {String} url
   */
  urlForFindMany: function(ids, modelName, snapshots) {
    return this._buildURL(modelName);
  },

  /**
   * @method urlForFindHasMany
   * @param {String} id
   * @param {String} modelName
   * @return {String} url
   */
  urlForFindHasMany: function(id, modelName) {
    return this._buildURL(modelName, id);
  },

  /**
   * @method urlForFindBelongTo
   * @param {String} id
   * @param {String} modelName
   * @return {String} url
   */
  urlForFindBelongsTo: function(id, modelName) {
    return this._buildURL(modelName, id);
  },

  /**
   * @method urlForCreateRecord
   * @param {String} modelName
   * @param {DS.Snapshot} snapshot
   * @return {String} url
   */
  urlForCreateRecord: function(modelName, snapshot) {
    return this._buildURL(modelName);
  },

  /**
   * @method urlForUpdateRecord
   * @param {String} id
   * @param {String} modelName
   * @param {DS.Snapshot} snapshot
   * @return {String} url
   */
  urlForUpdateRecord: function(id, modelName, snapshot) {
    return this._buildURL(modelName, id);
  },

  /**
   * @method urlForDeleteRecord
   * @param {String} id
   * @param {String} modelName
   * @param {DS.Snapshot} snapshot
   * @return {String} url
   */
  urlForDeleteRecord: function(id, modelName, snapshot) {
    return this._buildURL(modelName, id);
  },

  /**
    @method urlPrefix
    @private
    @param {String} path
    @param {String} parentUrl
    @return {String} urlPrefix
  */
  urlPrefix: function(path, parentURL) {
    var host = get(this, 'host');
    var namespace = get(this, 'namespace');
    var url = [];

    if (path) {
      // Protocol relative url
      //jscs:disable disallowEmptyBlocks
      if (/^\/\//.test(path)) {
        // Do nothing, the full host is already included. This branch
        // avoids the absolute path logic and the relative path logic.

      // Absolute path
      } else if (path.charAt(0) === '/') {
        //jscs:enable disallowEmptyBlocks
        if (host) {
          path = path.slice(1);
          url.push(host);
        }
      // Relative path
      } else if (!/^http(s)?:\/\//.test(path)) {
        url.push(parentURL);
      }
    } else {
      if (host) { url.push(host); }
      if (namespace) { url.push(namespace); }
    }

    if (path) {
      url.push(path);
    }

    return url.join('/');
  },

  /**
    Determines the pathname for a given type.

    By default, it pluralizes the type's name (for example,
    'post' becomes 'posts' and 'person' becomes 'people').

    ### Pathname customization

    For example if you have an object LineItem with an
    endpoint of "/line_items/".

    ```js
    App.ApplicationAdapter = DS.RESTAdapter.extend({
      pathForType: function(modelName) {
        var decamelized = Ember.String.decamelize(modelName);
        return Ember.String.pluralize(decamelized);
      }
    });
    ```

    @method pathForType
    @param {String} modelName
    @return {String} path
  **/
  pathForType: function(modelName) {
    var camelized = Ember.String.camelize(modelName);
    return Ember.String.pluralize(camelized);
  }
});


text:
/*
	Direct port of and compatible with the cross platform 'sync' library:  https://github.com/cubiclesoft/cross-platform-cpp
	This source file is under the MIT license.
	(C) 2016 CubicleSoft.  All rights reserved.
*/

/* $Id$ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "zend_exceptions.h"
#include "ext/standard/info.h"
#if defined(PHP_WIN32) && PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 4
#include "win32/php_stdint.h"
#else
#include <stdint.h>
#endif

/* Macros.  Oh joy. */
#if PHP_MAJOR_VERSION >= 7
#include "zend_portability.h"
#endif

#include "php_sync.h"
#define PORTABLE_default_zend_object_name   std

/* PHP_FE_END not defined in PHP < 5.3.7 */
#ifndef PHP_FE_END
#define PHP_FE_END {NULL, NULL, NULL}
#endif

/* For PHP 8 */
#ifndef TSRMLS_D
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#define TSRMLS_FETCH()
#endif

/* {{{ sync_module_entry
 */
zend_module_entry sync_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
	STANDARD_MODULE_HEADER,
#endif
	"sync",
	NULL,
	PHP_MINIT(sync),
	PHP_MSHUTDOWN(sync),
	NULL,
	NULL,
	PHP_MINFO(sync),
#if ZEND_MODULE_API_NO >= 20010901
	PHP_SYNC_VERSION,
#endif
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_SYNC
ZEND_GET_MODULE(sync)
#endif

#ifndef INFINITE
#	define INFINITE   0xFFFFFFFF
#endif

/* Define some generic functions used several places. */
#if defined(PHP_WIN32)

/* Windows. */
sync_ThreadIDType sync_GetCurrentThreadID()
{
	return GetCurrentThreadId();
}

uint64_t sync_GetUnixMicrosecondTime()
{
	FILETIME TempTime;
	ULARGE_INTEGER TempTime2;
	uint64_t Result;

	GetSystemTimeAsFileTime(&TempTime);
	TempTime2.HighPart = TempTime.dwHighDateTime;
	TempTime2.LowPart = TempTime.dwLowDateTime;
	Result = TempTime2.QuadPart;

	Result = (Result / 10) - (uint64_t)11644473600000000ULL;

	return Result;
}

#else

/* POSIX pthreads. */
sync_ThreadIDType sync_GetCurrentThreadID()
{
	return pthread_self();
}

uint64_t sync_GetUnixMicrosecondTime()
{
	struct timeval TempTime;

	if (gettimeofday(&TempTime, NULL))  return 0;

	return (uint64_t)((uint64_t)TempTime.tv_sec * (uint64_t)1000000 + (uint64_t)TempTime.tv_usec);
}

/* Dear Apple:  You hire plenty of developers, so please fix your OS. */
int sync_CSGX__ClockGetTimeRealtime(struct timespec *ts)
{
#ifdef __APPLE__
	clock_serv_t cclock;
	mach_timespec_t mts;

	if (host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock) != KERN_SUCCESS)  return -1;
	if (clock_get_time(cclock, &mts) != KERN_SUCCESS)  return -1;
	if (mach_port_deallocate(mach_task_self(), cclock) != KERN_SUCCESS)  return -1;

	ts->tv_sec = mts.tv_sec;
	ts->tv_nsec = mts.tv_nsec;

	return 0;
#else
	return clock_gettime(CLOCK_REALTIME, ts);
#endif
}

size_t sync_GetUnixSystemAlignmentSize()
{
	struct {
		int MxInt;
	} x;

	struct {
		int MxInt;
		char MxChar;
	} y;

	return sizeof(y) - sizeof(x);
}

size_t sync_AlignUnixSize(size_t Size)
{
	size_t AlignSize = sync_GetUnixSystemAlignmentSize();

	if (Size % AlignSize)  Size += AlignSize - (Size % AlignSize);

	return Size;
}

int sync_InitUnixNamedMem(char **ResultMem, size_t *StartPos, const char *Prefix, const char *Name, size_t Size)
{
	int Result = -1;
	*ResultMem = NULL;
	*StartPos = (Name != NULL ? sync_AlignUnixSize(1) + sync_AlignUnixSize(sizeof(pthread_mutex_t)) + sync_AlignUnixSize(sizeof(uint32_t)) : 0);

	/* First byte indicates initialization status (0 = completely uninitialized, 1 = first mutex initialized, 2 = ready). */
	/* Next few bytes are a shared mutex object. */
	/* Size bytes follow for whatever. */
	Size += *StartPos;
	Size = sync_AlignUnixSize(Size);

	if (Name == NULL)
	{
		*ResultMem = (char *)ecalloc(1, Size);

		Result = 0;
	}
	else
	{
		/* Deal with really small name limits with a pseudo-hash. */
		char Name2[SHM_NAME_MAX], Nums[50];
		size_t x, x2 = 0, y = strlen(Prefix), z = 0;

		memset(Name2, 0, sizeof(Name2));

		for (x = 0; x < y; x++)
		{
			Name2[x2] = (char)(((unsigned int)(unsigned char)Name2[x2]) * 37 + ((unsigned int)(unsigned char)Prefix[x]));
			x2++;

			if (x2 == sizeof(Name2) - 1)
			{
				x2 = 1;
				z++;
			}
		}

		sprintf(Nums, "-%u-%u-", (unsigned int)sync_GetUnixSystemAlignmentSize(), (unsigned int)Size);

		y = strlen(Nums);
		for (x = 0; x < y; x++)
		{
			Name2[x2] = (char)(((unsigned int)(unsigned char)Name2[x2]) * 37 + ((unsigned int)(unsigned char)Nums[x]));
			x2++;

			if (x2 == sizeof(Name2) - 1)
			{
				x2 = 1;
				z++;
			}
		}

		y = strlen(Name);
		for (x = 0; x < y; x++)
		{
			Name2[x2] = (char)(((unsigned int)(unsigned char)Name2[x2]) * 37 + ((unsigned int)(unsigned char)Name[x]));
			x2++;

			if (x2 == sizeof(Name2) - 1)
			{
				x2 = 1;
				z++;
			}
		}

		/* Normalize the alphabet if it looped. */
		if (z)
		{
			unsigned char TempChr;
			y = (z > 1 ? sizeof(Name2) - 1 : x2);
			for (x = 1; x < y; x++)
			{
				TempChr = ((unsigned char)Name2[x]) & 0x3F;

				if (TempChr < 10)  TempChr += '0';
				else if (TempChr < 36)  TempChr = TempChr - 10 + 'A';
				else if (TempChr < 62)  TempChr = TempChr - 36 + 'a';
				else if (TempChr == 62)  TempChr = '_';
				else  TempChr = '-';

				Name2[x] = (char)TempChr;
			}
		}

		for (x = 1; x < sizeof(Name2) && Name2[x]; x++)
		{
			if (Name2[x] == '\\' || Name2[x] == '/')  Name2[x] = '_';
		}

		pthread_mutex_t *MutexPtr;
		uint32_t *RefCountPtr;

		/* Attempt to create the named shared memory object. */
		mode_t PrevMask = umask(0);
		int fp = shm_open(Name2, O_RDWR | O_CREAT | O_EXCL, 0666);
		if (fp > -1)
		{
			/* Ignore platform errors (for now). */
			while (ftruncate(fp, Size) < 0 && errno == EINTR)
			{
			}

			*ResultMem = (char *)mmap(NULL, Size, PROT_READ | PROT_WRITE, MAP_SHARED, fp, 0);
			if ((*ResultMem) == MAP_FAILED)  *ResultMem = NULL;
			else
			{
				pthread_mutexattr_t MutexAttr;

				pthread_mutexattr_init(&MutexAttr);
				pthread_mutexattr_setpshared(&MutexAttr, PTHREAD_PROCESS_SHARED);

				MutexPtr = (pthread_mutex_t *)((*ResultMem) + sync_AlignUnixSize(1));
				RefCountPtr = (uint32_t *)((*ResultMem) + sync_AlignUnixSize(1) + sync_AlignUnixSize(sizeof(pthread_mutex_t)));

				pthread_mutex_init(MutexPtr, &MutexAttr);
				pthread_mutex_lock(MutexPtr);

				(*ResultMem)[0] = '\x01';
				RefCountPtr[0] = 1;

				Result = 0;
			}

			close(fp);
		}
		else
		{
			/* Attempt to open the named shared memory object. */
			fp = shm_open(Name2, O_RDWR, 0666);
			if (fp > -1)
			{
				/* Ignore platform errors (for now). */
				while (ftruncate(fp, Size) < 0 && errno == EINTR)
				{
				}

				*ResultMem = (char *)mmap(NULL, Size, PROT_READ | PROT_WRITE, MAP_SHARED, fp, 0);
				if (*ResultMem == MAP_FAILED)  ResultMem = NULL;
				else
				{
					/* Wait until the space is fully initialized. */
					if ((*ResultMem)[0] == '\x00')
					{
						while ((*ResultMem)[0] == '\x00')
						{
							usleep(2000);
						}
					}

					char *MemPtr = (*ResultMem) + sync_AlignUnixSize(1);
					MutexPtr = (pthread_mutex_t *)(MemPtr);
					MemPtr += sync_AlignUnixSize(sizeof(pthread_mutex_t));

					RefCountPtr = (uint32_t *)(MemPtr);
					MemPtr += sync_AlignUnixSize(sizeof(uint32_t));

					pthread_mutex_lock(MutexPtr);

					if (RefCountPtr[0])  Result = 1;
					else
					{
						/* If this is the first reference, reset the RAM to 0's for platform consistency to force a rebuild of the object. */
						memset(MemPtr, 0, Size);

						Result = 0;
					}

					RefCountPtr[0]++;

					pthread_mutex_unlock(MutexPtr);
				}

				close(fp);
			}
		}

		umask(PrevMask);
	}

	return Result;
}

void sync_UnixNamedMemReady(char *MemPtr)
{
	pthread_mutex_unlock((pthread_mutex_t *)(MemPtr + sync_AlignUnixSize(1)));
}

void sync_UnmapUnixNamedMem(char *MemPtr, size_t Size)
{
	pthread_mutex_t *MutexPtr;
	uint32_t *RefCountPtr;

	char *MemPtr2 = MemPtr + sync_AlignUnixSize(1);
	MutexPtr = (pthread_mutex_t *)(MemPtr2);
	MemPtr2 += sync_AlignUnixSize(sizeof(pthread_mutex_t));

	RefCountPtr = (uint32_t *)(MemPtr2);

	pthread_mutex_lock(MutexPtr);
	if (RefCountPtr[0])  RefCountPtr[0]--;
	pthread_mutex_unlock(MutexPtr);

	munmap(MemPtr, sync_AlignUnixSize(1) + sync_AlignUnixSize(sizeof(pthread_mutex_t)) + sync_AlignUnixSize(sizeof(uint32_t)) + Size);
}

/* Basic *NIX Semaphore functions. */
size_t sync_GetUnixSemaphoreSize()
{
	return sync_AlignUnixSize(sizeof(pthread_mutex_t)) + sync_AlignUnixSize(sizeof(uint32_t)) + sync_AlignUnixSize(sizeof(uint32_t)) + sync_AlignUnixSize(sizeof(pthread_cond_t));
}

void sync_GetUnixSemaphore(sync_UnixSemaphoreWrapper *Result, char *Mem)
{
	Result->MxMutex = (pthread_mutex_t *)(Mem);
	Mem += sync_AlignUnixSize(sizeof(pthread_mutex_t));

	Result->MxCount = (uint32_t *)(Mem);
	Mem += sync_AlignUnixSize(sizeof(uint32_t));

	Result->MxMax = (uint32_t *)(Mem);
	Mem += sync_AlignUnixSize(sizeof(uint32_t));

	Result->MxCond = (pthread_cond_t *)(Mem);
}

void sync_InitUnixSemaphore(sync_UnixSemaphoreWrapper *UnixSemaphore, int Shared, uint32_t Start, uint32_t Max)
{
	pthread_mutexattr_t MutexAttr;
	pthread_condattr_t CondAttr;

	pthread_mutexattr_init(&MutexAttr);
	pthread_condattr_init(&CondAttr);

	if (Shared)
	{
		pthread_mutexattr_setpshared(&MutexAttr, PTHREAD_PROCESS_SHARED);
		pthread_condattr_setpshared(&CondAttr, PTHREAD_PROCESS_SHARED);
	}

	pthread_mutex_init(UnixSemaphore->MxMutex, &MutexAttr);
	if (Start > Max)  Start = Max;
	UnixSemaphore->MxCount[0] = Start;
	UnixSemaphore->MxMax[0] = Max;
	pthread_cond_init(UnixSemaphore->MxCond, &CondAttr);

	pthread_condattr_destroy(&CondAttr);
	pthread_mutexattr_destroy(&MutexAttr);
}

int sync_WaitForUnixSemaphore(sync_UnixSemaphoreWrapper *UnixSemaphore, uint32_t Wait)
{
	if (Wait == 0)
	{
		/* Avoid the scenario of deadlock on the semaphore itself for 0 wait. */
		if (pthread_mutex_trylock(UnixSemaphore->MxMutex) != 0)  return 0;
	}
	else
	{
		if (pthread_mutex_lock(UnixSemaphore->MxMutex) != 0)  return 0;
	}

	int Result = 0;

	if (UnixSemaphore->MxCount[0])
	{
		UnixSemaphore->MxCount[0]--;

		Result = 1;
	}
	else if (Wait == INFINITE)
	{
		int Result2;
		do
		{
			Result2 = pthread_cond_wait(UnixSemaphore->MxCond, UnixSemaphore->MxMutex);
			if (Result2 != 0)  break;
		} while (!UnixSemaphore->MxCount[0]);

		if (Result2 == 0)
		{
			UnixSemaphore->MxCount[0]--;

			Result = 1;
		}
	}
	else if (Wait == 0)
	{
		/* Failed to obtain lock.  Nothing to do. */
	}
	else
	{
		struct timespec TempTime;

		if (sync_CSGX__ClockGetTimeRealtime(&TempTime) == -1)  return 0;
		TempTime.tv_sec += Wait / 1000;
		TempTime.tv_nsec += (Wait % 1000) * 1000000;
		TempTime.tv_sec += TempTime.tv_nsec / 1000000000;
		TempTime.tv_nsec = TempTime.tv_nsec % 1000000000;

		int Result2;
		do
		{
			/* Some platforms have pthread_cond_timedwait() but not pthread_mutex_timedlock() or sem_timedwait() (e.g. Mac OSX). */
			Result2 = pthread_cond_timedwait(UnixSemaphore->MxCond, UnixSemaphore->MxMutex, &TempTime);
			if (Result2 != 0)  break;
		} while (!UnixSemaphore->MxCount[0]);

		if (Result2 == 0)
		{
			UnixSemaphore->MxCount[0]--;

			Result = 1;
		}
	}

	pthread_mutex_unlock(UnixSemaphore->MxMutex);

	return Result;
}

int sync_ReleaseUnixSemaphore(sync_UnixSemaphoreWrapper *UnixSemaphore, uint32_t *PrevVal)
{
	if (pthread_mutex_lock(UnixSemaphore->MxMutex) != 0)  return 0;

	if (PrevVal != NULL)  *PrevVal = UnixSemaphore->MxCount[0];
	UnixSemaphore->MxCount[0]++;
	if (UnixSemaphore->MxCount[0] > UnixSemaphore->MxMax[0])  UnixSemaphore->MxCount[0] = UnixSemaphore->MxMax[0];

	/* Let a waiting thread have at it. */
	pthread_cond_signal(UnixSemaphore->MxCond);

	pthread_mutex_unlock(UnixSemaphore->MxMutex);

	return 1;
}

void sync_FreeUnixSemaphore(sync_UnixSemaphoreWrapper *UnixSemaphore)
{
	pthread_mutex_destroy(UnixSemaphore->MxMutex);
	pthread_cond_destroy(UnixSemaphore->MxCond);
}

/* Basic *NIX Event functions. */
size_t sync_GetUnixEventSize()
{
	return sync_AlignUnixSize(sizeof(pthread_mutex_t)) + sync_AlignUnixSize(2) + sync_AlignUnixSize(sizeof(uint32_t)) + sync_AlignUnixSize(sizeof(pthread_cond_t));
}

void sync_GetUnixEvent(sync_UnixEventWrapper *Result, char *Mem)
{
	Result->MxMutex = (pthread_mutex_t *)(Mem);
	Mem += sync_AlignUnixSize(sizeof(pthread_mutex_t));

	Result->MxManual = Mem;
	Result->MxSignaled = Mem + 1;
	Mem += sync_AlignUnixSize(2);

	Result->MxWaiting = (uint32_t *)(Mem);
	Mem += sync_AlignUnixSize(sizeof(uint32_t));

	Result->MxCond = (pthread_cond_t *)(Mem);
}

void sync_InitUnixEvent(sync_UnixEventWrapper *UnixEvent, int Shared, int Manual, int Signaled)
{
	pthread_mutexattr_t MutexAttr;
	pthread_condattr_t CondAttr;

	pthread_mutexattr_init(&MutexAttr);
	pthread_condattr_init(&CondAttr);

	if (Shared)
	{
		pthread_mutexattr_setpshared(&MutexAttr, PTHREAD_PROCESS_SHARED);
		pthread_condattr_setpshared(&CondAttr, PTHREAD_PROCESS_SHARED);
	}

	pthread_mutex_init(UnixEvent->MxMutex, &MutexAttr);
	UnixEvent->MxManual[0] = (Manual ? '\x01' : '\x00');
	UnixEvent->MxSignaled[0] = (Signaled ? '\x01' : '\x00');
	UnixEvent->MxWaiting[0] = 0;
	pthread_cond_init(UnixEvent->MxCond, &CondAttr);

	pthread_condattr_destroy(&CondAttr);
	pthread_mutexattr_destroy(&MutexAttr);
}

int sync_WaitForUnixEvent(sync_UnixEventWrapper *UnixEvent, uint32_t Wait)
{
	if (Wait == 0)
	{
		/* Avoid the scenario of deadlock on the semaphore itself for 0 wait. */
		if (pthread_mutex_trylock(UnixEvent->MxMutex) != 0)  return 0;
	}
	else
	{
		if (pthread_mutex_lock(UnixEvent->MxMutex) != 0)  return 0;
	}

	int Result = 0;

	/* Avoid a potential starvation issue by only allowing signaled manual events OR if there are no other waiting threads. */
	if (UnixEvent->MxSignaled[0] != '\x00' && (UnixEvent->MxManual[0] != '\x00' || !UnixEvent->MxWaiting[0]))
	{
		/* Reset auto events. */
		if (UnixEvent->MxManual[0] == '\x00')  UnixEvent->MxSignaled[0] = '\x00';

		Result = 1;
	}
	else if (Wait == INFINITE)
	{
		UnixEvent->MxWaiting[0]++;

		int Result2;
		do
		{
			Result2 = pthread_cond_wait(UnixEvent->MxCond, UnixEvent->MxMutex);
			if (Result2 != 0)  break;
		} while (UnixEvent->MxSignaled[0] == '\x00');

		UnixEvent->MxWaiting[0]--;

		if (Result2 == 0)
		{
			/* Reset auto events. */
			if (UnixEvent->MxManual[0] == '\x00')  UnixEvent->MxSignaled[0] = '\x00';

			Result = 1;
		}
	}
	else if (Wait == 0)
	{
		/* Failed to obtain lock.  Nothing to do. */
	}
	else
	{
		struct timespec TempTime;

		if (sync_CSGX__ClockGetTimeRealtime(&TempTime) == -1)
		{
			pthread_mutex_unlock(UnixEvent->MxMutex);

			return 0;
		}

		TempTime.tv_sec += Wait / 1000;
		TempTime.tv_nsec += (Wait % 1000) * 1000000;
		TempTime.tv_sec += TempTime.tv_nsec / 1000000000;
		TempTime.tv_nsec = TempTime.tv_nsec % 1000000000;

		UnixEvent->MxWaiting[0]++;

		int Result2;
		do
		{
			/* Some platforms have pthread_cond_timedwait() but not pthread_mutex_timedlock() or sem_timedwait() (e.g. Mac OSX). */
			Result2 = pthread_cond_timedwait(UnixEvent->MxCond, UnixEvent->MxMutex, &TempTime);
			if (Result2 != 0)  break;
		} while (UnixEvent->MxSignaled[0] == '\x00');

		UnixEvent->MxWaiting[0]--;

		if (Result2 == 0)
		{
			/* Reset auto events. */
			if (UnixEvent->MxManual[0] == '\x00')  UnixEvent->MxSignaled[0] = '\x00';

			Result = 1;
		}
	}

	pthread_mutex_unlock(UnixEvent->MxMutex);

	return Result;
}

int sync_FireUnixEvent(sync_UnixEventWrapper *UnixEvent)
{
	if (pthread_mutex_lock(UnixEvent->MxMutex) != 0)  return 0;

	UnixEvent->MxSignaled[0] = '\x01';

	/* Let all waiting threads through for manual events, otherwise just one waiting thread (if any). */
	if (UnixEvent->MxManual[0] != '\x00')  pthread_cond_broadcast(UnixEvent->MxCond);
	else  pthread_cond_signal(UnixEvent->MxCond);

	pthread_mutex_unlock(UnixEvent->MxMutex);

	return 1;
}

/* Only call for manual events. */
int sync_ResetUnixEvent(sync_UnixEventWrapper *UnixEvent)
{
	if (UnixEvent->MxManual[0] == '\x00')  return 0;
	if (pthread_mutex_lock(UnixEvent->MxMutex) != 0)  return 0;

	UnixEvent->MxSignaled[0] = '\x00';

	pthread_mutex_unlock(UnixEvent->MxMutex);

	return 1;
}

void sync_FreeUnixEvent(sync_UnixEventWrapper *UnixEvent)
{
	pthread_mutex_destroy(UnixEvent->MxMutex);
	pthread_cond_destroy(UnixEvent->MxCond);
}

#endif

/* {{{ PHP 5 and 7 crossover compatibility defines and functions */
#if PHP_MAJOR_VERSION >= 7

#define PORTABLE_new_zend_object_func(funcname)   zend_object *funcname(zend_class_entry *ce)
#define PORTABLE_new_zend_object_return_var
#define PORTABLE_new_zend_object_return_var_ref   NULL
#define PORTABLE_allocate_zend_object(size, ce)   ecalloc(1, (size) + zend_object_properties_size(ce));
#define PORTABLE_new_zend_object_return(std)   return (std)

void PORTABLE_InitZendObject(void *obj, zend_object *std, void *unused1, void *FreeFunc, zend_object_handlers *Handlers, zend_class_entry *ce TSRMLS_DC)
{
	/* Initialize Zend. */
	zend_object_std_init(std, ce TSRMLS_CC);
	object_properties_init(std, ce);

	/* Initialize destructor callback. */
	std->handlers = Handlers;
}

typedef zend_long   PORTABLE_ZPP_ARG_long;
typedef size_t   PORTABLE_ZPP_ARG_size;
typedef zval *   PORTABLE_ZPP_ARG_zval_ref;
#define PORTABLE_ZPP_ARG_zval_ref_deref(var)   var

static inline void *PHP_7_zend_object_to_object(zend_object *std)
{
	return (void *)((char *)std - std->handlers->offset);
}

#define PORTABLE_zend_object_store_get_object()   PHP_7_zend_object_to_object(Z_OBJ_P(getThis()))

#define PORTABLE_free_zend_object_func(funcname)   void funcname(zend_object *object)
#define PORTABLE_free_zend_object_get_object(object)   PHP_7_zend_object_to_object(object)
#define PORTABLE_free_zend_object_free_object(obj)   zend_object_std_dtor(&obj->std);

#define PORTABLE_RETURN_STRINGL(str, len)   RETURN_STRINGL(str, len)

#else

#define PORTABLE_new_zend_object_func(funcname)   zend_object_value funcname(zend_class_entry *ce TSRMLS_DC)
#define PORTABLE_new_zend_object_return_var   zend_object_value retval
#define PORTABLE_new_zend_object_return_var_ref   &retval
#define PORTABLE_new_zend_object_return(std)   return retval
#define PORTABLE_allocate_zend_object(size, ce)   ecalloc(1, (size));

void PORTABLE_InitZendObject(void *obj, zend_object *std, zend_object_value *retval, zend_objects_free_object_storage_t FreeFunc, zend_object_handlers *Handlers, zend_class_entry *ce TSRMLS_DC)
{
#if PHP_VERSION_ID < 50399
	zval *tmp;
#endif

	/* Initialize Zend. */
	zend_object_std_init(std, ce TSRMLS_CC);
#if PHP_VERSION_ID < 50399
	zend_hash_copy(std->properties, &ce->default_properties, (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
	object_properties_init(std, ce);
#endif

	/* Initialize destructor callback. */
	retval->handle = zend_objects_store_put(obj, (zend_objects_store_dtor_t)zend_objects_destroy_object, FreeFunc, NULL TSRMLS_CC);
	retval->handlers = Handlers;
}

typedef long   PORTABLE_ZPP_ARG_long;
typedef int   PORTABLE_ZPP_ARG_size;
typedef zval **   PORTABLE_ZPP_ARG_zval_ref;
#define PORTABLE_ZPP_ARG_zval_ref_deref(var)   *var

#define PORTABLE_zend_object_store_get_object()   zend_object_store_get_object(getThis() TSRMLS_CC)

#define PORTABLE_free_zend_object_func(funcname)   void funcname(void *object TSRMLS_DC)
#define PORTABLE_free_zend_object_get_object(object)   object;
#define PORTABLE_free_zend_object_free_object(obj)   zend_object_std_dtor(&obj->std TSRMLS_CC);  efree(obj);

#define PORTABLE_RETURN_STRINGL(str, len)   RETURN_STRINGL(str, len, 1)

#endif
/* }}} */

/* Mutex */
PHP_SYNC_API zend_class_entry *sync_Mutex_ce;
static zend_object_handlers sync_Mutex_object_handlers;

PORTABLE_free_zend_object_func(sync_Mutex_free_object);

/* {{{ Initialize internal Mutex structure. */
PORTABLE_new_zend_object_func(sync_Mutex_create_object)
{
	PORTABLE_new_zend_object_return_var;
	sync_Mutex_object *obj;

	/* Create the object. */
	obj = (sync_Mutex_object *)PORTABLE_allocate_zend_object(sizeof(sync_Mutex_object), ce);

	PORTABLE_InitZendObject(obj, &obj->std, PORTABLE_new_zend_object_return_var_ref, sync_Mutex_free_object, &sync_Mutex_object_handlers, ce TSRMLS_CC);

	/* Initialize Mutex information. */
#if defined(PHP_WIN32)
	obj->MxWinMutex = NULL;
	InitializeCriticalSection(&obj->MxWinCritSection);
#else
	obj->MxNamed = 0;
	obj->MxMem = NULL;
	pthread_mutex_init(&obj->MxPthreadCritSection, NULL);
#endif
	obj->MxOwnerID = 0;
	obj->MxCount = 0;

	PORTABLE_new_zend_object_return(&obj->std);
}
/* }}} */

/* {{{ Unlocks a mutex. */
int sync_Mutex_unlock_internal(sync_Mutex_object *obj, int all)
{
#if defined(PHP_WIN32)

	EnterCriticalSection(&obj->MxWinCritSection);

	/* Make sure the mutex exists and make sure it is owned by the calling thread. */
	if (obj->MxWinMutex == NULL || obj->MxOwnerID != sync_GetCurrentThreadID())
	{
		LeaveCriticalSection(&obj->MxWinCritSection);

		return 0;
	}

	if (all)  obj->MxCount = 1;

	obj->MxCount--;
	if (!obj->MxCount)
	{
		obj->MxOwnerID = 0;

		/* Release the mutex. */
		ReleaseMutex(obj->MxWinMutex);
	}

	LeaveCriticalSection(&obj->MxWinCritSection);

#else

	if (pthread_mutex_lock(&obj->MxPthreadCritSection) != 0)  return 0;

	/* Make sure the mutex exists and make sure it is owned by the calling thread. */
	if (obj->MxMem == NULL || obj->MxOwnerID != sync_GetCurrentThreadID())
	{
		pthread_mutex_unlock(&obj->MxPthreadCritSection);

		return 0;
	}

	if (all)  obj->MxCount = 1;

	obj->MxCount--;
	if (!obj->MxCount)
	{
		obj->MxOwnerID = 0;

		/* Release the mutex. */
		sync_ReleaseUnixSemaphore(&obj->MxPthreadMutex, NULL);
	}

	pthread_mutex_unlock(&obj->MxPthreadCritSection);

#endif

	return 1;
}
/* }}} */

/* {{{ Free internal Mutex structure. */
PORTABLE_free_zend_object_func(sync_Mutex_free_object)
{
	sync_Mutex_object *obj = (sync_Mutex_object *)PORTABLE_free_zend_object_get_object(object);

	sync_Mutex_unlock_internal(obj, 1);

#if defined(PHP_WIN32)
	if (obj->MxWinMutex != NULL)  CloseHandle(obj->MxWinMutex);
	DeleteCriticalSection(&obj->MxWinCritSection);
#else
	if (obj->MxMem != NULL)
	{
		if (obj->MxNamed)  sync_UnmapUnixNamedMem(obj->MxMem, sync_GetUnixSemaphoreSize());
		else
		{
			sync_FreeUnixSemaphore(&obj->MxPthreadMutex);

			efree(obj->MxMem);
		}
	}

	pthread_mutex_destroy(&obj->MxPthreadCritSection);
#endif

	PORTABLE_free_zend_object_free_object(obj);
}
/* }}} */

/* {{{ proto void Sync_Mutex::__construct([string $name = null])
   Constructs a named or unnamed mutex object. */
PHP_METHOD(sync_Mutex, __construct)
{
	char *name = NULL;
	PORTABLE_ZPP_ARG_size name_len;
	sync_Mutex_object *obj;
#if defined(PHP_WIN32)
	SECURITY_ATTRIBUTES SecAttr;
#else
	size_t Pos, TempSize;
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE)  return;

	obj = (sync_Mutex_object *)PORTABLE_zend_object_store_get_object();

	if (name_len < 1)  name = NULL;

#if defined(PHP_WIN32)

	SecAttr.nLength = sizeof(SecAttr);
	SecAttr.lpSecurityDescriptor = NULL;
	SecAttr.bInheritHandle = TRUE;

	obj->MxWinMutex = CreateMutexA(&SecAttr, FALSE, name);
	if (obj->MxWinMutex == NULL)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Mutex could not be created", 0 TSRMLS_CC);
		return;
	}

#else

	TempSize = sync_GetUnixSemaphoreSize();
	obj->MxNamed = (name != NULL ? 1 : 0);
	int Result = sync_InitUnixNamedMem(&obj->MxMem, &Pos, "/Sync_Mutex", name, TempSize);

	if (Result < 0)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Mutex could not be created", 0 TSRMLS_CC);

		return;
	}

	sync_GetUnixSemaphore(&obj->MxPthreadMutex, obj->MxMem + Pos);

	/* Handle the first time this mutex has been opened. */
	if (Result == 0)
	{
		sync_InitUnixSemaphore(&obj->MxPthreadMutex, obj->MxNamed, 1, 1);

		if (obj->MxNamed)  sync_UnixNamedMemReady(obj->MxMem);
	}

#endif
}
/* }}} */

/* {{{ proto bool Sync_Mutex::lock([int $wait = -1])
   Locks a mutex object. */
PHP_METHOD(sync_Mutex, lock)
{
	PORTABLE_ZPP_ARG_long wait = -1;
	sync_Mutex_object *obj;
#if defined(PHP_WIN32)
	DWORD Result;
#else
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &wait) == FAILURE)  return;

	obj = (sync_Mutex_object *)PORTABLE_zend_object_store_get_object();

#if defined(PHP_WIN32)

	EnterCriticalSection(&obj->MxWinCritSection);

	/* Check to see if this is already owned by the calling thread. */
	if (obj->MxOwnerID == sync_GetCurrentThreadID())
	{
		obj->MxCount++;
		LeaveCriticalSection(&obj->MxWinCritSection);

		RETURN_TRUE;
	}

	LeaveCriticalSection(&obj->MxWinCritSection);

	/* Acquire the mutex. */
	Result = WaitForSingleObject(obj->MxWinMutex, (DWORD)(wait > -1 ? wait : INFINITE));
	if (Result != WAIT_OBJECT_0)  RETURN_FALSE;

	EnterCriticalSection(&obj->MxWinCritSection);
	obj->MxOwnerID = sync_GetCurrentThreadID();
	obj->MxCount = 1;
	LeaveCriticalSection(&obj->MxWinCritSection);

#else

	if (pthread_mutex_lock(&obj->MxPthreadCritSection) != 0)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Unable to acquire mutex critical section", 0 TSRMLS_CC);

		RETURN_FALSE;
	}

	/* Check to see if this mutex is already owned by the calling thread. */
	if (obj->MxOwnerID == sync_GetCurrentThreadID())
	{
		obj->MxCount++;
		pthread_mutex_unlock(&obj->MxPthreadCritSection);

		RETURN_TRUE;
	}

	pthread_mutex_unlock(&obj->MxPthreadCritSection);

	if (!sync_WaitForUnixSemaphore(&obj->MxPthreadMutex, (uint32_t)(wait > -1 ? wait : INFINITE)))  RETURN_FALSE;

	pthread_mutex_lock(&obj->MxPthreadCritSection);
	obj->MxOwnerID = sync_GetCurrentThreadID();
	obj->MxCount = 1;
	pthread_mutex_unlock(&obj->MxPthreadCritSection);

#endif

	RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool Sync_Mutex::unlock([bool $all = false])
   Unlocks a mutex object. */
PHP_METHOD(sync_Mutex, unlock)
{
	PORTABLE_ZPP_ARG_long all = 0;
	sync_Mutex_object *obj;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &all) == FAILURE)  return;

	obj = (sync_Mutex_object *)PORTABLE_zend_object_store_get_object();

	if (!sync_Mutex_unlock_internal(obj, all))  RETURN_FALSE;

	RETURN_TRUE;
}
/* }}} */

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_mutex___construct, 0, 0, 0)
	ZEND_ARG_INFO(0, name)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_mutex_lock, 0, 0, 0)
	ZEND_ARG_INFO(0, wait)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_mutex_unlock, 0, 0, 0)
	ZEND_ARG_INFO(0, all)
ZEND_END_ARG_INFO()

static const zend_function_entry sync_Mutex_methods[] = {
	PHP_ME(sync_Mutex, __construct, arginfo_sync_mutex___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
	PHP_ME(sync_Mutex, lock, arginfo_sync_mutex_lock, ZEND_ACC_PUBLIC)
	PHP_ME(sync_Mutex, unlock, arginfo_sync_mutex_unlock, ZEND_ACC_PUBLIC)
	PHP_FE_END
};

/* Semaphore */
PHP_SYNC_API zend_class_entry *sync_Semaphore_ce;
static zend_object_handlers sync_Semaphore_object_handlers;

PORTABLE_free_zend_object_func(sync_Semaphore_free_object);

/* {{{ Initialize internal Semaphore structure. */
PORTABLE_new_zend_object_func(sync_Semaphore_create_object)
{
	PORTABLE_new_zend_object_return_var;
	sync_Semaphore_object *obj;

	/* Create the object. */
	obj = (sync_Semaphore_object *)PORTABLE_allocate_zend_object(sizeof(sync_Semaphore_object), ce);

	PORTABLE_InitZendObject(obj, &obj->std, PORTABLE_new_zend_object_return_var_ref, sync_Semaphore_free_object, &sync_Semaphore_object_handlers, ce TSRMLS_CC);

	/* Initialize Semaphore information. */
#if defined(PHP_WIN32)
	obj->MxWinSemaphore = NULL;
#else
	obj->MxNamed = 0;
	obj->MxMem = NULL;
#endif
	obj->MxAutoUnlock = 0;
	obj->MxCount = 0;

	PORTABLE_new_zend_object_return(&obj->std);
}
/* }}} */

/* {{{ Free internal Semaphore structure. */
PORTABLE_free_zend_object_func(sync_Semaphore_free_object)
{
	sync_Semaphore_object *obj = (sync_Semaphore_object *)PORTABLE_free_zend_object_get_object(object);

	if (obj->MxAutoUnlock)
	{
		while (obj->MxCount)
		{
#if defined(PHP_WIN32)
			ReleaseSemaphore(obj->MxWinSemaphore, 1, NULL);
#else
			sync_ReleaseUnixSemaphore(&obj->MxPthreadSemaphore, NULL);
#endif

			obj->MxCount--;
		}
	}

#if defined(PHP_WIN32)
	if (obj->MxWinSemaphore != NULL)  CloseHandle(obj->MxWinSemaphore);
#else
	if (obj->MxMem != NULL)
	{
		if (obj->MxNamed)  sync_UnmapUnixNamedMem(obj->MxMem, sync_GetUnixSemaphoreSize());
		else
		{
			sync_FreeUnixSemaphore(&obj->MxPthreadSemaphore);

			efree(obj->MxMem);
		}
	}
#endif

	PORTABLE_free_zend_object_free_object(obj);
}
/* }}} */

/* {{{ proto void Sync_Semaphore::__construct([string $name = null, [int $initialval = 1, [bool $autounlock = true]]])
   Constructs a named or unnamed semaphore object.  Don't set $autounlock to false unless you really know what you are doing. */
PHP_METHOD(sync_Semaphore, __construct)
{
	char *name = NULL;
	PORTABLE_ZPP_ARG_size name_len;
	PORTABLE_ZPP_ARG_long initialval = 1;
	PORTABLE_ZPP_ARG_long autounlock = 1;
	sync_Semaphore_object *obj;
#if defined(PHP_WIN32)
	SECURITY_ATTRIBUTES SecAttr;
#else
	size_t Pos, TempSize;
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sll", &name, &name_len, &initialval, &autounlock) == FAILURE)  return;

	obj = (sync_Semaphore_object *)PORTABLE_zend_object_store_get_object();

	if (name_len < 1)  name = NULL;

	obj->MxAutoUnlock = (autounlock ? 1 : 0);

#if defined(PHP_WIN32)

	SecAttr.nLength = sizeof(SecAttr);
	SecAttr.lpSecurityDescriptor = NULL;
	SecAttr.bInheritHandle = TRUE;

	obj->MxWinSemaphore = CreateSemaphoreA(&SecAttr, (LONG)initialval, (LONG)initialval, name);
	if (obj->MxWinSemaphore == NULL)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Semaphore could not be created", 0 TSRMLS_CC);
		return;
	}

#else

	TempSize = sync_GetUnixSemaphoreSize();
	obj->MxNamed = (name != NULL ? 1 : 0);
	int Result = sync_InitUnixNamedMem(&obj->MxMem, &Pos, "/Sync_Semaphore", name, TempSize);

	if (Result < 0)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Semaphore could not be created", 0 TSRMLS_CC);

		return;
	}

	sync_GetUnixSemaphore(&obj->MxPthreadSemaphore, obj->MxMem + Pos);

	/* Handle the first time this semaphore has been opened. */
	if (Result == 0)
	{
		sync_InitUnixSemaphore(&obj->MxPthreadSemaphore, obj->MxNamed, (uint32_t)initialval, (uint32_t)initialval);

		if (obj->MxNamed)  sync_UnixNamedMemReady(obj->MxMem);
	}

#endif
}
/* }}} */

/* {{{ proto bool Sync_Semaphore::lock([int $wait = -1])
   Locks a semaphore object. */
PHP_METHOD(sync_Semaphore, lock)
{
	PORTABLE_ZPP_ARG_long wait = -1;
	sync_Semaphore_object *obj;
#if defined(PHP_WIN32)
	DWORD Result;
#else
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &wait) == FAILURE)  return;

	obj = (sync_Semaphore_object *)PORTABLE_zend_object_store_get_object();

#if defined(PHP_WIN32)

	Result = WaitForSingleObject(obj->MxWinSemaphore, (DWORD)(wait > -1 ? wait : INFINITE));
	if (Result != WAIT_OBJECT_0)  RETURN_FALSE;

#else

	if (!sync_WaitForUnixSemaphore(&obj->MxPthreadSemaphore, (uint32_t)(wait > -1 ? wait : INFINITE)))  RETURN_FALSE;

#endif

	if (obj->MxAutoUnlock)  obj->MxCount++;

	RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool Sync_Semaphore::unlock([int &$prevcount])
   Unlocks a semaphore object. */
PHP_METHOD(sync_Semaphore, unlock)
{
	PORTABLE_ZPP_ARG_zval_ref zprevcount = NULL;
	sync_Semaphore_object *obj;
	PORTABLE_ZPP_ARG_long count;
#if defined(PHP_WIN32)
	LONG PrevCount;
#else
	uint32_t PrevCount;
#endif

#if PHP_MAJOR_VERSION >= 7
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/", &zprevcount) == FAILURE)  return;
#else
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Z", &zprevcount) == FAILURE)  return;
#endif

	obj = (sync_Semaphore_object *)PORTABLE_zend_object_store_get_object();

#if defined(PHP_WIN32)

	if (!ReleaseSemaphore(obj->MxWinSemaphore, 1, &PrevCount))  RETURN_FALSE;

#else

	sync_ReleaseUnixSemaphore(&obj->MxPthreadSemaphore, &PrevCount);

#endif

	if (zprevcount != NULL)
	{
		count = (PORTABLE_ZPP_ARG_long)PrevCount;

		zval_dtor(PORTABLE_ZPP_ARG_zval_ref_deref(zprevcount));
		ZVAL_LONG(PORTABLE_ZPP_ARG_zval_ref_deref(zprevcount), count);
	}

	if (obj->MxAutoUnlock)  obj->MxCount--;

	RETURN_TRUE;
}
/* }}} */

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_semaphore___construct, 0, 0, 0)
	ZEND_ARG_INFO(0, name)
	ZEND_ARG_INFO(0, initialval)
	ZEND_ARG_INFO(0, autounlock)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_semaphore_lock, 0, 0, 0)
	ZEND_ARG_INFO(0, wait)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_semaphore_unlock, 0, 0, 0)
	ZEND_ARG_INFO(1, prevcount)
ZEND_END_ARG_INFO()

static const zend_function_entry sync_Semaphore_methods[] = {
	PHP_ME(sync_Semaphore, __construct, arginfo_sync_semaphore___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
	PHP_ME(sync_Semaphore, lock, arginfo_sync_semaphore_lock, ZEND_ACC_PUBLIC)
	PHP_ME(sync_Semaphore, unlock, arginfo_sync_semaphore_unlock, ZEND_ACC_PUBLIC)
	PHP_FE_END
};

/* Event */
PHP_SYNC_API zend_class_entry *sync_Event_ce;
static zend_object_handlers sync_Event_object_handlers;

PORTABLE_free_zend_object_func(sync_Event_free_object);

/* {{{ Initialize internal Event structure. */
PORTABLE_new_zend_object_func(sync_Event_create_object)
{
	PORTABLE_new_zend_object_return_var;
	sync_Event_object *obj;

	/* Create the object. */
	obj = (sync_Event_object *)PORTABLE_allocate_zend_object(sizeof(sync_Event_object), ce);

	PORTABLE_InitZendObject(obj, &obj->std, PORTABLE_new_zend_object_return_var_ref, sync_Event_free_object, &sync_Event_object_handlers, ce TSRMLS_CC);

	/* Initialize Event information. */
#if defined(PHP_WIN32)
	obj->MxWinWaitEvent = NULL;
#else
	obj->MxNamed = 0;
	obj->MxMem = NULL;
#endif

	PORTABLE_new_zend_object_return(&obj->std);
}
/* }}} */

/* {{{ Free internal Event structure. */
PORTABLE_free_zend_object_func(sync_Event_free_object)
{
	sync_Event_object *obj = (sync_Event_object *)PORTABLE_free_zend_object_get_object(object);

#if defined(PHP_WIN32)
	if (obj->MxWinWaitEvent != NULL)  CloseHandle(obj->MxWinWaitEvent);
#else
	if (obj->MxMem != NULL)
	{
		if (obj->MxNamed)  sync_UnmapUnixNamedMem(obj->MxMem, sync_GetUnixEventSize());
		else
		{
			sync_FreeUnixEvent(&obj->MxPthreadEvent);

			efree(obj->MxMem);
		}
	}
#endif

	PORTABLE_free_zend_object_free_object(obj);
}
/* }}} */

/* {{{ proto void Sync_Event::__construct([string $name = null, [bool $manual = false, [bool $prefire = false]]])
   Constructs a named or unnamed event object. */
PHP_METHOD(sync_Event, __construct)
{
	char *name = NULL;
	PORTABLE_ZPP_ARG_size name_len;
	PORTABLE_ZPP_ARG_long manual = 0, prefire = 0;
	sync_Event_object *obj;
#if defined(PHP_WIN32)
	SECURITY_ATTRIBUTES SecAttr;
#else
	size_t Pos, TempSize;
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sll", &name, &name_len, &manual, &prefire) == FAILURE)  return;

	obj = (sync_Event_object *)PORTABLE_zend_object_store_get_object();

	if (name_len < 1)  name = NULL;

#if defined(PHP_WIN32)

	SecAttr.nLength = sizeof(SecAttr);
	SecAttr.lpSecurityDescriptor = NULL;
	SecAttr.bInheritHandle = TRUE;

	obj->MxWinWaitEvent = CreateEventA(&SecAttr, (BOOL)manual, (prefire ? TRUE : FALSE), name);
	if (obj->MxWinWaitEvent == NULL)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Event object could not be created", 0 TSRMLS_CC);
		return;
	}

#else

	TempSize = sync_GetUnixEventSize();
	obj->MxNamed = (name != NULL ? 1 : 0);
	int Result = sync_InitUnixNamedMem(&obj->MxMem, &Pos, "/Sync_Event", name, TempSize);

	if (Result < 0)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Event object could not be created", 0 TSRMLS_CC);

		return;
	}

	sync_GetUnixEvent(&obj->MxPthreadEvent, obj->MxMem + Pos);

	/* Handle the first time this event has been opened. */
	if (Result == 0)
	{
		sync_InitUnixEvent(&obj->MxPthreadEvent, obj->MxNamed, (manual ? 1 : 0), (prefire ? 1 : 0));

		if (obj->MxNamed)  sync_UnixNamedMemReady(obj->MxMem);
	}

#endif
}
/* }}} */

/* {{{ proto bool Sync_Event::wait([int $wait = -1])
   Waits for an event object to fire. */
PHP_METHOD(sync_Event, wait)
{
	PORTABLE_ZPP_ARG_long wait = -1;
	sync_Event_object *obj;
#if defined(PHP_WIN32)
	DWORD Result;
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &wait) == FAILURE)  return;

	obj = (sync_Event_object *)PORTABLE_zend_object_store_get_object();

#if defined(PHP_WIN32)

	Result = WaitForSingleObject(obj->MxWinWaitEvent, (DWORD)(wait > -1 ? wait : INFINITE));
	if (Result != WAIT_OBJECT_0)  RETURN_FALSE;

#else

	if (!sync_WaitForUnixEvent(&obj->MxPthreadEvent, (uint32_t)(wait > -1 ? wait : INFINITE)))  RETURN_FALSE;

#endif

	RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool Sync_Event::fire()
   Lets a thread through that is waiting.  Lets multiple threads through that are waiting if the event object is 'manual'. */
PHP_METHOD(sync_Event, fire)
{
	sync_Event_object *obj;

	obj = (sync_Event_object *)PORTABLE_zend_object_store_get_object();

#if defined(PHP_WIN32)

	if (!SetEvent(obj->MxWinWaitEvent))  RETURN_FALSE;

#else

	if (!sync_FireUnixEvent(&obj->MxPthreadEvent))  RETURN_FALSE;

#endif

	RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool Sync_Event::reset()
   Resets the event object state.  Only use when the event object is 'manual'. */
PHP_METHOD(sync_Event, reset)
{
	sync_Event_object *obj;

	obj = (sync_Event_object *)PORTABLE_zend_object_store_get_object();

#if defined(PHP_WIN32)

	if (!ResetEvent(obj->MxWinWaitEvent))  RETURN_FALSE;

#else

	if (!sync_ResetUnixEvent(&obj->MxPthreadEvent))  RETURN_FALSE;

#endif

	RETURN_TRUE;
}
/* }}} */

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_event___construct, 0, 0, 0)
	ZEND_ARG_INFO(0, name)
	ZEND_ARG_INFO(0, manual)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_event_wait, 0, 0, 0)
	ZEND_ARG_INFO(0, wait)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_event_fire, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_event_reset, 0, 0, 0)
ZEND_END_ARG_INFO()

static const zend_function_entry sync_Event_methods[] = {
	PHP_ME(sync_Event, __construct, arginfo_sync_event___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
	PHP_ME(sync_Event, wait, arginfo_sync_event_wait, ZEND_ACC_PUBLIC)
	PHP_ME(sync_Event, fire, arginfo_sync_event_fire, ZEND_ACC_PUBLIC)
	PHP_ME(sync_Event, reset, arginfo_sync_event_reset, ZEND_ACC_PUBLIC)
	PHP_FE_END
};

/* Reader-Writer */
PHP_SYNC_API zend_class_entry *sync_ReaderWriter_ce;
static zend_object_handlers sync_ReaderWriter_object_handlers;

PORTABLE_free_zend_object_func(sync_ReaderWriter_free_object);

/* {{{ Initialize internal Reader-Writer structure. */
PORTABLE_new_zend_object_func(sync_ReaderWriter_create_object)
{
	PORTABLE_new_zend_object_return_var;
	sync_ReaderWriter_object *obj;

	/* Create the object. */
	obj = (sync_ReaderWriter_object *)PORTABLE_allocate_zend_object(sizeof(sync_ReaderWriter_object), ce);

	PORTABLE_InitZendObject(obj, &obj->std, PORTABLE_new_zend_object_return_var_ref, sync_ReaderWriter_free_object, &sync_ReaderWriter_object_handlers, ce TSRMLS_CC);

	/* Initialize Reader-Writer information. */
#if defined(PHP_WIN32)
	obj->MxWinRSemMutex = NULL;
	obj->MxWinRSemaphore = NULL;
	obj->MxWinRWaitEvent = NULL;
	obj->MxWinWWaitMutex = NULL;
#else
	obj->MxNamed = 0;
	obj->MxMem = NULL;
	obj->MxRCount = NULL;
#endif

	obj->MxAutoUnlock = 1;
	obj->MxReadLocks = 0;
	obj->MxWriteLock = 0;

	PORTABLE_new_zend_object_return(&obj->std);
}
/* }}} */

/* {{{ Unlocks a read lock. */
int sync_ReaderWriter_readunlock_internal(sync_ReaderWriter_object *obj)
{
#if defined(PHP_WIN32)

	DWORD Result;
	LONG Val;

	if (obj->MxWinRSemMutex == NULL || obj->MxWinRSemaphore == NULL || obj->MxWinRWaitEvent == NULL)  return 0;

	/* Acquire the semaphore mutex. */
	Result = WaitForSingleObject(obj->MxWinRSemMutex, INFINITE);
	if (Result != WAIT_OBJECT_0)  return 0;

	if (obj->MxReadLocks)  obj->MxReadLocks--;

	/* Release the semaphore. */
	if (!ReleaseSemaphore(obj->MxWinRSemaphore, 1, &Val))
	{
		ReleaseSemaphore(obj->MxWinRSemMutex, 1, NULL);

		return 0;
	}

	/* Update the event state. */
	if (Val == LONG_MAX - 1)
	{
		if (!SetEvent(obj->MxWinRWaitEvent))
		{
			ReleaseSemaphore(obj->MxWinRSemMutex, 1, NULL);

			return 0;
		}
	}

	/* Release the semaphore mutex. */
	ReleaseSemaphore(obj->MxWinRSemMutex, 1, NULL);

#else

	if (obj->MxMem == NULL)  return 0;

	/* Acquire the counter mutex. */
	if (!sync_WaitForUnixSemaphore(&obj->MxPthreadRCountMutex, INFINITE))  return 0;

	if (obj->MxReadLocks)  obj->MxReadLocks--;

	/* Decrease the number of readers. */
	if (obj->MxRCount[0])  obj->MxRCount[0]--;
	else
	{
		sync_ReleaseUnixSemaphore(&obj->MxPthreadRCountMutex, NULL);

		return 0;
	}

	/* Update the event state. */
	if (!obj->MxRCount[0] && !sync_FireUnixEvent(&obj->MxPthreadRWaitEvent))
	{
		sync_ReleaseUnixSemaphore(&obj->MxPthreadRCountMutex, NULL);

		return 0;
	}

	/* Release the counter mutex. */
	sync_ReleaseUnixSemaphore(&obj->MxPthreadRCountMutex, NULL);

#endif

	return 1;
}
/* }}} */

/* {{{ Unlocks a write lock. */
int sync_ReaderWriter_writeunlock_internal(sync_ReaderWriter_object *obj)
{
#if defined(PHP_WIN32)

	if (obj->MxWinWWaitMutex == NULL)  return 0;

	obj->MxWriteLock = 0;

	/* Release the write lock. */
	ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

#else

	if (obj->MxMem == NULL)  return 0;

	obj->MxWriteLock = 0;

	/* Release the write lock. */
	sync_ReleaseUnixSemaphore(&obj->MxPthreadWWaitMutex, NULL);

#endif

	return 1;
}
/* }}} */

/* {{{ Free internal Reader-Writer structure. */
PORTABLE_free_zend_object_func(sync_ReaderWriter_free_object)
{
	sync_ReaderWriter_object *obj = (sync_ReaderWriter_object *)PORTABLE_free_zend_object_get_object(object);

	if (obj->MxAutoUnlock)
	{
		while (obj->MxReadLocks)  sync_ReaderWriter_readunlock_internal(obj);

		if (obj->MxWriteLock)  sync_ReaderWriter_writeunlock_internal(obj);
	}

#if defined(PHP_WIN32)
	if (obj->MxWinWWaitMutex != NULL)  CloseHandle(obj->MxWinWWaitMutex);
	if (obj->MxWinRWaitEvent != NULL)  CloseHandle(obj->MxWinRWaitEvent);
	if (obj->MxWinRSemaphore != NULL)  CloseHandle(obj->MxWinRSemaphore);
	if (obj->MxWinRSemMutex != NULL)  CloseHandle(obj->MxWinRSemMutex);
#else
	if (obj->MxMem != NULL)
	{
		if (obj->MxNamed)  sync_UnmapUnixNamedMem(obj->MxMem, sync_GetUnixSemaphoreSize() + sync_AlignUnixSize(sizeof(uint32_t)) + sync_GetUnixEventSize() + sync_GetUnixSemaphoreSize());
		else
		{
			sync_FreeUnixSemaphore(&obj->MxPthreadRCountMutex);
			sync_FreeUnixEvent(&obj->MxPthreadRWaitEvent);
			sync_FreeUnixSemaphore(&obj->MxPthreadWWaitMutex);

			efree(obj->MxMem);
		}
	}
#endif

	PORTABLE_free_zend_object_free_object(obj);
}
/* }}} */

/* {{{ proto void Sync_ReaderWriter::__construct([string $name = null, [bool $autounlock = true]])
   Constructs a named or unnamed reader-writer object.  Don't set $autounlock to false unless you really know what you are doing. */
PHP_METHOD(sync_ReaderWriter, __construct)
{
	char *name = NULL;
	PORTABLE_ZPP_ARG_size name_len;
	PORTABLE_ZPP_ARG_long autounlock = 1;
	sync_ReaderWriter_object *obj;
#if defined(PHP_WIN32)
	char *name2;
	SECURITY_ATTRIBUTES SecAttr;
#else
	size_t Pos, TempSize;
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &name, &name_len, &autounlock) == FAILURE)  return;

	obj = (sync_ReaderWriter_object *)PORTABLE_zend_object_store_get_object();

	if (name_len < 1)  name = NULL;

	obj->MxAutoUnlock = (autounlock ? 1 : 0);

#if defined(PHP_WIN32)

	if (name == NULL)  name2 = NULL;
	else  name2 = emalloc(name_len + 20);

	SecAttr.nLength = sizeof(SecAttr);
	SecAttr.lpSecurityDescriptor = NULL;
	SecAttr.bInheritHandle = TRUE;

	/* Create the mutexes, semaphore, and event objects. */
	if (name2 != NULL)  sprintf(name2, "%s-Sync_ReadWrite-0", name);
	obj->MxWinRSemMutex = CreateSemaphoreA(&SecAttr, 1, 1, name2);
	if (name2 != NULL)  sprintf(name2, "%s-Sync_ReadWrite-1", name);
	obj->MxWinRSemaphore = CreateSemaphoreA(&SecAttr, LONG_MAX, LONG_MAX, name2);
	if (name2 != NULL)  sprintf(name2, "%s-Sync_ReadWrite-2", name);
	obj->MxWinRWaitEvent = CreateEventA(&SecAttr, TRUE, TRUE, name2);
	if (name2 != NULL)  sprintf(name2, "%s-Sync_ReadWrite-3", name);
	obj->MxWinWWaitMutex = CreateSemaphoreA(&SecAttr, 1, 1, name2);

	if (name2 != NULL)  efree(name2);

	if (obj->MxWinRSemMutex == NULL || obj->MxWinRSemaphore == NULL || obj->MxWinRWaitEvent == NULL || obj->MxWinWWaitMutex == NULL)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Reader-Writer object could not be created", 0 TSRMLS_CC);

		return;
	}

#else

	TempSize = sync_GetUnixSemaphoreSize() + sync_AlignUnixSize(sizeof(uint32_t)) + sync_GetUnixEventSize() + sync_GetUnixSemaphoreSize();
	obj->MxNamed = (name != NULL ? 1 : 0);
	int Result = sync_InitUnixNamedMem(&obj->MxMem, &Pos, "/Sync_ReadWrite", name, TempSize);

	if (Result < 0)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Reader-Writer object could not be created", 0 TSRMLS_CC);

		return;
	}

	/* Load the pointers. */
	char *MemPtr = obj->MxMem + Pos;
	sync_GetUnixSemaphore(&obj->MxPthreadRCountMutex, MemPtr);
	MemPtr += sync_GetUnixSemaphoreSize();

	obj->MxRCount = (volatile uint32_t *)(MemPtr);
	MemPtr += sync_AlignUnixSize(sizeof(uint32_t));

	sync_GetUnixEvent(&obj->MxPthreadRWaitEvent, MemPtr);
	MemPtr += sync_GetUnixEventSize();

	sync_GetUnixSemaphore(&obj->MxPthreadWWaitMutex, MemPtr);

	/* Handle the first time this reader/writer lock has been opened. */
	if (Result == 0)
	{
		sync_InitUnixSemaphore(&obj->MxPthreadRCountMutex, obj->MxNamed, 1, 1);
		obj->MxRCount[0] = 0;
		sync_InitUnixEvent(&obj->MxPthreadRWaitEvent, obj->MxNamed, 1, 1);
		sync_InitUnixSemaphore(&obj->MxPthreadWWaitMutex, obj->MxNamed, 1, 1);

		if (obj->MxNamed)  sync_UnixNamedMemReady(obj->MxMem);
	}

#endif
}
/* }}} */

/* {{{ proto bool Sync_ReaderWriter::readlock([int $wait = -1])
   Read locks a reader-writer object. */
PHP_METHOD(sync_ReaderWriter, readlock)
{
	PORTABLE_ZPP_ARG_long wait = -1;
	sync_ReaderWriter_object *obj;
	uint32_t WaitAmt;
	uint64_t StartTime, CurrTime;
#if defined(PHP_WIN32)
	DWORD Result;
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &wait) == FAILURE)  return;

	obj = (sync_ReaderWriter_object *)PORTABLE_zend_object_store_get_object();

	WaitAmt = (uint32_t)(wait > -1 ? wait : INFINITE);

	/* Get current time in milliseconds. */
	StartTime = (WaitAmt == INFINITE ? 0 : sync_GetUnixMicrosecondTime() / 1000000);

#if defined(PHP_WIN32)

	/* Acquire the write lock mutex.  Guarantees that readers can't starve the writer. */
	Result = WaitForSingleObject(obj->MxWinWWaitMutex, WaitAmt);
	if (Result != WAIT_OBJECT_0)  RETURN_FALSE;

	/* Acquire the semaphore mutex. */
	CurrTime = (WaitAmt == INFINITE ? 0 : sync_GetUnixMicrosecondTime() / 1000000);
	if (WaitAmt < CurrTime - StartTime)
	{
		ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

		RETURN_FALSE;
	}
	Result = WaitForSingleObject(obj->MxWinRSemMutex, WaitAmt - (DWORD)(CurrTime - StartTime));
	if (Result != WAIT_OBJECT_0)
	{
		ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

		RETURN_FALSE;
	}

	/* Acquire the semaphore. */
	CurrTime = (WaitAmt == INFINITE ? 0 : sync_GetUnixMicrosecondTime() / 1000000);
	if (WaitAmt < CurrTime - StartTime)
	{
		ReleaseSemaphore(obj->MxWinRSemMutex, 1, NULL);
		ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

		RETURN_FALSE;
	}
	Result = WaitForSingleObject(obj->MxWinRSemaphore, WaitAmt - (DWORD)(CurrTime - StartTime));
	if (Result != WAIT_OBJECT_0)
	{
		ReleaseSemaphore(obj->MxWinRSemMutex, 1, NULL);
		ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

		RETURN_FALSE;
	}

	/* Update the event state. */
	if (!ResetEvent(obj->MxWinRWaitEvent))
	{
		ReleaseSemaphore(obj->MxWinRSemaphore, 1, NULL);
		ReleaseSemaphore(obj->MxWinRSemMutex, 1, NULL);
		ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

		RETURN_FALSE;
	}

	obj->MxReadLocks++;

	/* Release the mutexes. */
	ReleaseSemaphore(obj->MxWinRSemMutex, 1, NULL);
	ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

#else

	/* Acquire the write lock mutex.  Guarantees that readers can't starve the writer. */
	if (!sync_WaitForUnixSemaphore(&obj->MxPthreadWWaitMutex, WaitAmt))  RETURN_FALSE;

	/* Acquire the counter mutex. */
	CurrTime = (WaitAmt == INFINITE ? 0 : sync_GetUnixMicrosecondTime() / 1000000);
	if (WaitAmt < CurrTime - StartTime || !sync_WaitForUnixSemaphore(&obj->MxPthreadRCountMutex, WaitAmt - (CurrTime - StartTime)))
	{
		sync_ReleaseUnixSemaphore(&obj->MxPthreadWWaitMutex, NULL);

		RETURN_FALSE;
	}

	/* Update the event state. */
	if (!sync_ResetUnixEvent(&obj->MxPthreadRWaitEvent))
	{
		sync_ReleaseUnixSemaphore(&obj->MxPthreadRCountMutex, NULL);
		sync_ReleaseUnixSemaphore(&obj->MxPthreadWWaitMutex, NULL);

		RETURN_FALSE;
	}

	/* Increment the number of readers. */
	obj->MxRCount[0]++;

	obj->MxReadLocks++;

	/* Release the mutexes. */
	sync_ReleaseUnixSemaphore(&obj->MxPthreadRCountMutex, NULL);
	sync_ReleaseUnixSemaphore(&obj->MxPthreadWWaitMutex, NULL);

#endif

	RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool Sync_ReaderWriter::writelock([int $wait = -1])
   Write locks a reader-writer object. */
PHP_METHOD(sync_ReaderWriter, writelock)
{
	PORTABLE_ZPP_ARG_long wait = -1;
	sync_ReaderWriter_object *obj;
	uint32_t WaitAmt;
	uint64_t StartTime, CurrTime;
#if defined(PHP_WIN32)
	DWORD Result;
#else
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &wait) == FAILURE)  return;

	obj = (sync_ReaderWriter_object *)PORTABLE_zend_object_store_get_object();

	WaitAmt = (uint32_t)(wait > -1 ? wait : INFINITE);

	/* Get current time in milliseconds. */
	StartTime = (WaitAmt == INFINITE ? 0 : sync_GetUnixMicrosecondTime() / 1000000);

#if defined(PHP_WIN32)

	/* Acquire the write lock mutex. */
	Result = WaitForSingleObject(obj->MxWinWWaitMutex, WaitAmt);
	if (Result != WAIT_OBJECT_0)  RETURN_FALSE;

	/* Wait for readers to reach zero. */
	CurrTime = (WaitAmt == INFINITE ? 0 : sync_GetUnixMicrosecondTime() / 1000000);
	Result = WaitForSingleObject(obj->MxWinRWaitEvent, WaitAmt - (DWORD)(CurrTime - StartTime));
	if (Result != WAIT_OBJECT_0)
	{
		ReleaseSemaphore(obj->MxWinWWaitMutex, 1, NULL);

		RETURN_FALSE;
	}

#else

	/* Acquire the write lock mutex. */
	if (!sync_WaitForUnixSemaphore(&obj->MxPthreadWWaitMutex, WaitAmt))  RETURN_FALSE;

	/* Wait for readers to reach zero. */
	CurrTime = (WaitAmt == INFINITE ? 0 : sync_GetUnixMicrosecondTime() / 1000000);
	if (WaitAmt < CurrTime - StartTime || !sync_WaitForUnixEvent(&obj->MxPthreadRWaitEvent, WaitAmt - (CurrTime - StartTime)))
	{
		sync_ReleaseUnixSemaphore(&obj->MxPthreadWWaitMutex, NULL);

		RETURN_FALSE;
	}

#endif

	obj->MxWriteLock = 1;

	RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool Sync_ReaderWriter::readunlock()
   Read unlocks a reader-writer object. */
PHP_METHOD(sync_ReaderWriter, readunlock)
{
	sync_ReaderWriter_object *obj;

	obj = (sync_ReaderWriter_object *)PORTABLE_zend_object_store_get_object();

	if (!sync_ReaderWriter_readunlock_internal(obj))  RETURN_FALSE;

	RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool Sync_ReaderWriter::writeunlock()
   Write unlocks a reader-writer object. */
PHP_METHOD(sync_ReaderWriter, writeunlock)
{
	sync_ReaderWriter_object *obj;

	obj = (sync_ReaderWriter_object *)PORTABLE_zend_object_store_get_object();

	if (!sync_ReaderWriter_writeunlock_internal(obj))  RETURN_FALSE;

	RETURN_TRUE;
}
/* }}} */

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_readerwriter___construct, 0, 0, 0)
	ZEND_ARG_INFO(0, name)
	ZEND_ARG_INFO(0, autounlock)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_readerwriter_readlock, 0, 0, 0)
	ZEND_ARG_INFO(0, wait)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_readerwriter_writelock, 0, 0, 0)
	ZEND_ARG_INFO(0, wait)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_readerwriter_readunlock, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_readerwriter_writeunlock, 0, 0, 0)
ZEND_END_ARG_INFO()

static const zend_function_entry sync_ReaderWriter_methods[] = {
	PHP_ME(sync_ReaderWriter, __construct, arginfo_sync_readerwriter___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
	PHP_ME(sync_ReaderWriter, readlock, arginfo_sync_readerwriter_readlock, ZEND_ACC_PUBLIC)
	PHP_ME(sync_ReaderWriter, writelock, arginfo_sync_readerwriter_writelock, ZEND_ACC_PUBLIC)
	PHP_ME(sync_ReaderWriter, readunlock, arginfo_sync_readerwriter_readunlock, ZEND_ACC_PUBLIC)
	PHP_ME(sync_ReaderWriter, writeunlock, arginfo_sync_readerwriter_writeunlock, ZEND_ACC_PUBLIC)
	PHP_FE_END
};

/* Shared Memory */
PHP_SYNC_API zend_class_entry *sync_SharedMemory_ce;
static zend_object_handlers sync_SharedMemory_object_handlers;

PORTABLE_free_zend_object_func(sync_SharedMemory_free_object);

/* {{{ Initialize internal Shared Memory structure. */
PORTABLE_new_zend_object_func(sync_SharedMemory_create_object)
{
	PORTABLE_new_zend_object_return_var;
	sync_SharedMemory_object *obj;

	/* Create the object. */
	obj = (sync_SharedMemory_object *)PORTABLE_allocate_zend_object(sizeof(sync_SharedMemory_object), ce);

	PORTABLE_InitZendObject(obj, &obj->std, PORTABLE_new_zend_object_return_var_ref, sync_SharedMemory_free_object, &sync_SharedMemory_object_handlers, ce TSRMLS_CC);

	/* Initialize Shared Memory information. */
#if defined(PHP_WIN32)
	obj->MxFile = NULL;
#else
	obj->MxMemInternal = NULL;
#endif

	obj->MxFirst = 0;
	obj->MxSize = 0;
	obj->MxMem = NULL;

	PORTABLE_new_zend_object_return(&obj->std);
}
/* }}} */

/* {{{ Free internal Shared Memory structure. */
PORTABLE_free_zend_object_func(sync_SharedMemory_free_object)
{
	sync_SharedMemory_object *obj = (sync_SharedMemory_object *)PORTABLE_free_zend_object_get_object(object);

#if defined(PHP_WIN32)
	if (obj->MxMem != NULL)  UnmapViewOfFile(obj->MxMem);
	if (obj->MxFile != NULL)  CloseHandle(obj->MxFile);
#else
	if (obj->MxMemInternal != NULL)  sync_UnmapUnixNamedMem(obj->MxMemInternal, obj->MxSize);
#endif

	PORTABLE_free_zend_object_free_object(obj);
}
/* }}} */

/* {{{ proto void Sync_SharedMemory::__construct(string $name, int $size)
   Constructs a named shared memory object. */
PHP_METHOD(sync_SharedMemory, __construct)
{
	char *name;
	PORTABLE_ZPP_ARG_size name_len;
	PORTABLE_ZPP_ARG_long size;
	sync_SharedMemory_object *obj;
#if defined(PHP_WIN32)
	char *name2;
	SECURITY_ATTRIBUTES SecAttr;
#else
	size_t Pos, TempSize;
#endif

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &name_len, &size) == FAILURE)  return;

	if (name_len < 1)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "An invalid name was passed", 0 TSRMLS_CC);

		return;
	}

	obj = (sync_SharedMemory_object *)PORTABLE_zend_object_store_get_object();

#if defined(PHP_WIN32)

	name2 = emalloc(name_len + 30);

	SecAttr.nLength = sizeof(SecAttr);
	SecAttr.lpSecurityDescriptor = NULL;
	SecAttr.bInheritHandle = TRUE;

	/* Create the file mapping object backed by the system page file. */
	sprintf(name2, "%s-%u-Sync_SharedMem", name, (unsigned int)size);
	obj->MxFile = CreateFileMappingA(INVALID_HANDLE_VALUE, &SecAttr, PAGE_READWRITE, 0, (DWORD)size, name2);
	if (obj->MxFile == NULL)
	{
		obj->MxFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, TRUE, name2);

		if (obj->MxFile == NULL)
		{
			zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Shared memory file mapping could not be created/opened", 0 TSRMLS_CC);

			return;
		}
	}
	else if (GetLastError() != ERROR_ALREADY_EXISTS)
	{
		obj->MxFirst = 1;
	}

	efree(name2);

	obj->MxMem = (char *)MapViewOfFile(obj->MxFile, FILE_MAP_ALL_ACCESS, 0, 0, (DWORD)size);

	if (obj->MxMem == NULL)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Shared memory segment could not be mapped", 0 TSRMLS_CC);

		return;
	}

	obj->MxSize = (size_t)size;

#else

	TempSize = (size_t)size;
	int Result = sync_InitUnixNamedMem(&obj->MxMemInternal, &Pos, "/Sync_SharedMem", name, TempSize);

	if (Result < 0)
	{
		zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Shared memory object could not be created/opened", 0 TSRMLS_CC);

		return;
	}

	/* Load the pointers. */
	obj->MxMem = obj->MxMemInternal + Pos;
	obj->MxSize = (size_t)size;

	/* Handle the first time this named memory has been opened. */
	if (Result == 0)
	{
		sync_UnixNamedMemReady(obj->MxMemInternal);

		obj->MxFirst = 1;
	}

#endif
}
/* }}} */

/* {{{ proto bool Sync_SharedMemory::first()
   Returns whether or not this shared memory segment is the first time accessed (i.e. not initialized). */
PHP_METHOD(sync_SharedMemory, first)
{
	sync_SharedMemory_object *obj;

	obj = (sync_SharedMemory_object *)PORTABLE_zend_object_store_get_object();

	RETURN_BOOL(obj->MxFirst);
}
/* }}} */

/* {{{ proto int Sync_SharedMemory::size()
   Returns the shared memory size. */
PHP_METHOD(sync_SharedMemory, size)
{
	sync_SharedMemory_object *obj;

	obj = (sync_SharedMemory_object *)PORTABLE_zend_object_store_get_object();

	RETURN_LONG((PORTABLE_ZPP_ARG_long)obj->MxSize);
}
/* }}} */

/* {{{ proto int Sync_SharedMemory::write(string $string, [int $start = 0])
   Copies data to shared memory. */
PHP_METHOD(sync_SharedMemory, write)
{
	char *str;
	PORTABLE_ZPP_ARG_size str_len;
	PORTABLE_ZPP_ARG_long start = 0, maxval;
	sync_SharedMemory_object *obj;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &start) == FAILURE)  return;

	obj = (sync_SharedMemory_object *)PORTABLE_zend_object_store_get_object();
	maxval = (PORTABLE_ZPP_ARG_long)obj->MxSize;

	if (start < 0)  start += maxval;
	if (start < 0)  start = 0;
	if (start > maxval)  start = maxval;

	if (start + str_len > maxval)  str_len = maxval - start;

	memcpy(obj->MxMem + (size_t)start, str, str_len);

	RETURN_LONG((PORTABLE_ZPP_ARG_long)str_len);
}
/* }}} */

/* {{{ proto string Sync_SharedMemory::read([int $start = 0, [int $length = null]])
   Copies data from shared memory. */
PHP_METHOD(sync_SharedMemory, read)
{
	PORTABLE_ZPP_ARG_long start = 0;
	PORTABLE_ZPP_ARG_long length, maxval;
	sync_SharedMemory_object *obj;

	obj = (sync_SharedMemory_object *)PORTABLE_zend_object_store_get_object();
	maxval = (PORTABLE_ZPP_ARG_long)obj->MxSize;
	length = maxval;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &start, &length) == FAILURE)  return;

	if (start < 0)  start += maxval;
	if (start < 0)  start = 0;
	if (start > maxval)  start = maxval;

	if (length < 0)  length += maxval - start;
	if (length < 0)  length = 0;
	if (start + length > maxval)  length = maxval - start;

	PORTABLE_RETURN_STRINGL(obj->MxMem + start, length);
}
/* }}} */

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_sharedmemory___construct, 0, 0, 2)
	ZEND_ARG_INFO(0, name)
	ZEND_ARG_INFO(0, size)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_sharedmemory_first, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_sharedmemory_size, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_sharedmemory_write, 0, 0, 1)
	ZEND_ARG_INFO(0, string)
	ZEND_ARG_INFO(0, start)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_sync_sharedmemory_read, 0, 0, 0)
	ZEND_ARG_INFO(0, start)
	ZEND_ARG_INFO(0, length)
ZEND_END_ARG_INFO()

static const zend_function_entry sync_SharedMemory_methods[] = {
	PHP_ME(sync_SharedMemory, __construct, arginfo_sync_sharedmemory___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
	PHP_ME(sync_SharedMemory, first, arginfo_sync_sharedmemory_first, ZEND_ACC_PUBLIC)
	PHP_ME(sync_SharedMemory, size, arginfo_sync_sharedmemory_size, ZEND_ACC_PUBLIC)
	PHP_ME(sync_SharedMemory, write, arginfo_sync_sharedmemory_write, ZEND_ACC_PUBLIC)
	PHP_ME(sync_SharedMemory, read, arginfo_sync_sharedmemory_read, ZEND_ACC_PUBLIC)
	PHP_FE_END
};

/* {{{ PHP_MINIT_FUNCTION(sync)
 */
PHP_MINIT_FUNCTION(sync)
{
	zend_class_entry ce;

	/* Mutex */
	memcpy(&sync_Mutex_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
	sync_Mutex_object_handlers.clone_obj = NULL;
#if PHP_MAJOR_VERSION >= 7
	sync_Mutex_object_handlers.offset = XtOffsetOf(sync_Mutex_object, PORTABLE_default_zend_object_name);
	sync_Mutex_object_handlers.free_obj = sync_Mutex_free_object;
#endif

	INIT_CLASS_ENTRY(ce, "SyncMutex", sync_Mutex_methods);
	ce.create_object = sync_Mutex_create_object;
	sync_Mutex_ce = zend_register_internal_class(&ce TSRMLS_CC);

	/* Semaphore */
	memcpy(&sync_Semaphore_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
	sync_Semaphore_object_handlers.clone_obj = NULL;
#if PHP_MAJOR_VERSION >= 7
	sync_Semaphore_object_handlers.offset = XtOffsetOf(sync_Semaphore_object, PORTABLE_default_zend_object_name);
	sync_Semaphore_object_handlers.free_obj = sync_Semaphore_free_object;
#endif

	INIT_CLASS_ENTRY(ce, "SyncSemaphore", sync_Semaphore_methods);
	ce.create_object = sync_Semaphore_create_object;
	sync_Semaphore_ce = zend_register_internal_class(&ce TSRMLS_CC);

	/* Event */
	memcpy(&sync_Event_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
	sync_Event_object_handlers.clone_obj = NULL;
#if PHP_MAJOR_VERSION >= 7
	sync_Event_object_handlers.offset = XtOffsetOf(sync_Event_object, PORTABLE_default_zend_object_name);
	sync_Event_object_handlers.free_obj = sync_Event_free_object;
#endif

	INIT_CLASS_ENTRY(ce, "SyncEvent", sync_Event_methods);
	ce.create_object = sync_Event_create_object;
	sync_Event_ce = zend_register_internal_class(&ce TSRMLS_CC);

	/* Reader-Writer */
	memcpy(&sync_ReaderWriter_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
	sync_ReaderWriter_object_handlers.clone_obj = NULL;
#if PHP_MAJOR_VERSION >= 7
	sync_ReaderWriter_object_handlers.offset = XtOffsetOf(sync_ReaderWriter_object, PORTABLE_default_zend_object_name);
	sync_ReaderWriter_object_handlers.free_obj = sync_ReaderWriter_free_object;
#endif

	INIT_CLASS_ENTRY(ce, "SyncReaderWriter", sync_ReaderWriter_methods);
	ce.create_object = sync_ReaderWriter_create_object;
	sync_ReaderWriter_ce = zend_register_internal_class(&ce TSRMLS_CC);

	/* Named Shared Memory */
	memcpy(&sync_SharedMemory_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
	sync_SharedMemory_object_handlers.clone_obj = NULL;
#if PHP_MAJOR_VERSION >= 7
	sync_SharedMemory_object_handlers.offset = XtOffsetOf(sync_SharedMemory_object, PORTABLE_default_zend_object_name);
	sync_SharedMemory_object_handlers.free_obj = sync_SharedMemory_free_object;
#endif

	INIT_CLASS_ENTRY(ce, "SyncSharedMemory", sync_SharedMemory_methods);
	ce.create_object = sync_SharedMemory_create_object;
	sync_SharedMemory_ce = zend_register_internal_class(&ce TSRMLS_CC);

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(sync)
{
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(sync)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "sync support", "enabled");
	php_info_print_table_end();
}
/* }}} */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */


text:
// Copyright 2016 Dino Wernli. All Rights Reserved. See LICENSE for licensing terms.

package me.dinowernli.grpc.prometheus;

import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import java.time.Clock;

/** A {@link ServerInterceptor} which sends stats about incoming grpc calls to Prometheus. */
public class MonitoringServerInterceptor implements ServerInterceptor {
  private final Clock clock;
  private final Configuration configuration;
  private final ServerMetrics.Factory serverMetricsFactory;

  public static MonitoringServerInterceptor create(Configuration configuration) {
    return new MonitoringServerInterceptor(
        Clock.systemDefaultZone(), configuration, new ServerMetrics.Factory(configuration));
  }

  private MonitoringServerInterceptor(
      Clock clock, Configuration configuration, ServerMetrics.Factory serverMetricsFactory) {
    this.clock = clock;
    this.configuration = configuration;
    this.serverMetricsFactory = serverMetricsFactory;
  }

  @Override
  public <R, S> ServerCall.Listener<R> interceptCall(
      ServerCall<R, S> call, Metadata requestMetadata, ServerCallHandler<R, S> next) {
    MethodDescriptor<R, S> methodDescriptor = call.getMethodDescriptor();
    GrpcMethod grpcMethod = GrpcMethod.of(methodDescriptor);
    ServerMetrics metrics = serverMetricsFactory.createMetricsForMethod(grpcMethod);
    ServerCall<R, S> monitoringCall =
        new MonitoringServerCall(call, clock, grpcMethod, metrics, configuration, requestMetadata);
    return new MonitoringServerCallListener<>(
        next.startCall(monitoringCall, requestMetadata), metrics, grpcMethod, requestMetadata);
  }
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.5"/>
<title>GraphBuilder 2.0 (alpha): com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

GraphBuilder 2.0 (alpha)

Overview

Javadoc

Files

          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Class List

Class Index

Class Hierarchy

Class Members

 All Classes Namespaces Files Functions Variables

com

intel

hadoop

graphbuilder

graphelements

callbacks

GraphElementDst

Public Member Functions |
List of all members

com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst Class Reference

Inheritance diagram for com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst:

  <map id="com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst_map" name="com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst_map">
</map>

Public Member Functions

Object 	edge (GraphElement graphElement, ArgumentBuilder arguments)

Object 	vertex (GraphElement graphElement, ArgumentBuilder arguments)

Detailed Description

Gets the graph elements

dst

 . If it's an edge it will return the

dst

 , otherwise it will return null.

See Also

com.intel.hadoop.graphbuilder.graphelements.GraphElement

Member Function Documentation

          Object com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst.edge
          (
          GraphElement
          graphElement,

          ArgumentBuilder
          arguments

          )

inline

Casts our graph element to an edge and get the edge's

dst

 .

Parameters

@code	graphElement  The graph element to perform operations on.

@code	arguments  Any arguments that might have been passed

Returns

The edge's

dst

 .

   41                                                                              {

   42         Edge edge = (Edge) graphElement;

   43         return edge.getDst();

   44     }

com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst.edge

Object edge(GraphElement graphElement, ArgumentBuilder arguments)

Definition: GraphElementDst.java:41

          Object com.intel.hadoop.graphbuilder.graphelements.callbacks.GraphElementDst.vertex
          (
          GraphElement
          graphElement,

          ArgumentBuilder
          arguments

          )

inline

Returns null because vertices do not have a

dst

 .

Parameters

@code	graphElement  The graph element to perform operations on.

@code	arguments  Any arguments that might have been passed.

Returns

Always null because vertices do not have a

dst

 .

   54                                                                                {

   55         return null;

   56     }

The documentation for this class was generated from the following file:

src/main/java/com/intel/hadoop/graphbuilder/graphelements/callbacks/GraphElementDst.java

<address class="footer">
Generated on Fri Dec 20 2013 18:43:59 for GraphBuilder 2.0 (alpha) by

 1.8.5
</address>


text:
<?php

namespace App\Entity\Crafting;

use Doctrine\ORM\Mapping as ORM;
/**
 * Class Resource
 *
 * @ORM\Entity
 * @ORM\Table(
 *     name="crafting__material",
 *     indexes={
 *          @ORM\Index(name="idx_material_code", columns={"code"})
 *      }
 * )
 */
class Material
{
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=50)
     */
    protected $name;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=50)
     */
    protected $code;

    /**
     * @var MaterialType
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Crafting\MaterialType")
     * @ORM\JoinColumn(name="material_type_id", referencedColumnName="id")
     */
    protected $materialType;

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param int $id
     *
     * @return Material
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     *
     * @return Material
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return string
     */
    public function getCode()
    {
        return $this->code;
    }

    /**
     * @param string $code
     *
     * @return Material
     */
    public function setCode($code)
    {
        $this->code = $code;

        return $this;
    }

    /**
     * @return MaterialType
     */
    public function getMaterialType()
    {
        return $this->materialType;
    }

    /**
     * @param MaterialType $materialType
     *
     * @return Material
     */
    public function setMaterialType($materialType)
    {
        $this->materialType = $materialType;

        return $this;
    }
}