jdk/src/jdk.jdi/share/native/libdt_shmem/shmemBase.c
author jwilhelm
Sat, 18 Feb 2017 03:23:28 +0100
changeset 43926 55bfd293eb16
parent 25859 3317bb8137f4
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
     2
 * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
#include <stdio.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#include <errno.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include "sysShmem.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "shmemBase.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "jdwpTransport.h"  /* for Packet, TransportCallback */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#define MIN(x,y) ((x)<(y)?(x):(y))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * This is the base shared memory transport implementation that is used
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * by both front-end transports (through com.sun.tools.jdi) and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * back-end transports (through JDWP_OnLoad and the function tables
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * it requires). It supports multiple connections for the benefit of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * front-end client; the back end interface assumes only a single connection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
#define MAX_IPC_PREFIX 50   /* user-specified or generated name for */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
                            /* shared memory seg and prefix for other IPC */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
#define MAX_IPC_SUFFIX 25   /* suffix to shmem name for other IPC names */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
#define MAX_IPC_NAME   (MAX_IPC_PREFIX + MAX_IPC_SUFFIX)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
#define MAX_GENERATION_RETRIES 20
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
#define SHARED_BUFFER_SIZE 5000
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
#define CHECK_ERROR(expr) do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
                              jint error = (expr); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
                              if (error != SYS_OK) { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
                                  setLastError(error); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
                                  return error; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
                              } \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
                          } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * The following assertions should hold anytime the stream's mutex is not held
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
#define STREAM_INVARIANT(stream) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
            SHMEM_ASSERT((stream->shared->readOffset < SHARED_BUFFER_SIZE) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
                         && (stream->shared->readOffset >= 0)); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            SHMEM_ASSERT((stream->shared->writeOffset < SHARED_BUFFER_SIZE) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
                         && (stream->shared->writeOffset >= 0)); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * Transports are duplex, so carve the shared memory into "streams",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * one used to send from client to server, the other vice versa.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
typedef struct SharedMemoryListener {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    char mutexName[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    char acceptEventName[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    char attachEventName[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    jboolean isListening;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    jboolean isAccepted;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    jlong acceptingPID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    jlong attachingPID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
} SharedListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
typedef struct SharedMemoryTransport {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    char name[MAX_IPC_PREFIX];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    sys_ipmutex_t mutex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    sys_event_t acceptEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    sys_event_t attachEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    sys_shmem_t sharedMemory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    SharedListener *shared;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
} SharedMemoryTransport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * Access must be syncronized.  Holds one shared
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * memory buffer and its state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
typedef struct SharedStream {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    char mutexName[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    char hasDataEventName[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    char hasSpaceEventName[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    int readOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    int writeOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    jboolean isFull;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    jbyte buffer[SHARED_BUFFER_SIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
} SharedStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * The two shared streams: client to server and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 * server to client.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
typedef struct SharedMemory {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    SharedStream toClient;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    SharedStream toServer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
} SharedMemory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 * Local (to process) access to the shared memory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 * stream.  access to hasData and hasSpace synchronized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 * by OS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
typedef struct Stream {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    sys_ipmutex_t mutex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    sys_event_t hasData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    sys_event_t hasSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    SharedStream *shared;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    jint state;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
} Stream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
 * Values for Stream.state field above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
#define STATE_CLOSED 0xDEAD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
#define STATE_OPEN   (STATE_CLOSED -1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
 * State checking macro. We compare against the STATE_OPEN value so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
 * that STATE_CLOSED and any other value will be considered closed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
 * This catches a freed Stream as long as the memory page is still
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
 * valid. If the memory page is gone, then there is little that we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
 * can do.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
#define IS_STATE_CLOSED(state) (state != STATE_OPEN)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
typedef struct SharedMemoryConnection {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    char name[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    SharedMemory *shared;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    sys_shmem_t sharedMemory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    Stream incoming;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    Stream outgoing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    sys_process_t otherProcess;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    sys_event_t shutdown;           /* signalled to indicate shutdown */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
} SharedMemoryConnection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
static jdwpTransportCallback *callback;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
static JavaVM *jvm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
static int tlsIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
typedef jint (*CreateFunc)(char *name, void *arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
 * Set the per-thread error message (if not already set)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
setLastErrorMsg(char *newmsg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    char *msg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    msg = (char *)sysTlsGet(tlsIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    if (msg == NULL) {
896
5c02031316bf 6725543: Compiler warnings in serviceability native code
ohair
parents: 2
diff changeset
   170
        msg = (*callback->alloc)((int)strlen(newmsg)+1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        if (msg != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
           strcpy(msg, newmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        sysTlsPut(tlsIndex, (void *)msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
 * Clear last per-thread error message
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
clearLastError() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    char* msg = (char *)sysTlsGet(tlsIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    if (msg != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        (*callback->free)(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        sysTlsPut(tlsIndex, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
 * Set the per-thread error message to the textual representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
 * of the last system error (if not already set)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
setLastError(jint error) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    char buf[128];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    switch (error) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        case SYS_OK      : return;      /* no-op */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        case SYS_DIED    : strcpy(buf, "Other process terminated"); break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        case SYS_TIMEOUT : strcpy(buf, "Timed out"); break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        default          : sysGetLastError(buf, sizeof(buf));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    setLastErrorMsg(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
shmemBase_initialize(JavaVM *vm, jdwpTransportCallback *cbPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    jvm = vm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    callback = cbPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    tlsIndex = sysTlsAlloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
createWithGeneratedName(char *prefix, char *nameBuffer, CreateFunc func, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    jint i = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        strcpy(nameBuffer, prefix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            char buf[10];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            sprintf(buf, ".%d", i+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            strcat(nameBuffer, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        error = func(nameBuffer, arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        i++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    } while ((error == SYS_INUSE) && (i < MAX_GENERATION_RETRIES));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
typedef struct SharedMemoryArg {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    jint size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    sys_shmem_t memory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    void *start;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
} SharedMemoryArg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
createSharedMem(char *name, void *ptr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    SharedMemoryArg *arg = ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    return sysSharedMemCreate(name, arg->size, &arg->memory, &arg->start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
createMutex(char *name, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    sys_ipmutex_t *retArg = arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    return sysIPMutexCreate(name, retArg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
 * Creates named or unnamed event that is automatically reset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
 * (in other words, no need to reset event after it has signalled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
 * a thread).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
createEvent(char *name, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    sys_event_t *retArg = arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    return sysEventCreate(name, retArg, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
#define ADD_OFFSET(o1, o2) ((o1 + o2) % SHARED_BUFFER_SIZE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
#define FULL(stream) (stream->shared->isFull)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
#define EMPTY(stream) ((stream->shared->writeOffset == stream->shared->readOffset) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                       && !stream->shared->isFull)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
leaveMutex(Stream *stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    return sysIPMutexExit(stream->mutex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
/* enter the stream's mutex and (optionally) check for a closed stream */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
enterMutex(Stream *stream, sys_event_t event)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    jint ret = sysIPMutexEnter(stream->mutex, event);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    if (ret != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        if (IS_STATE_CLOSED(stream->state)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            setLastErrorMsg("stream closed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    if (IS_STATE_CLOSED(stream->state)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        setLastErrorMsg("stream closed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        (void)leaveMutex(stream);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        return SYS_ERR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
 * Enter/exit with stream mutex held.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
 * On error, does not hold the stream mutex.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
waitForSpace(SharedMemoryConnection *connection, Stream *stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    jint error = SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    /* Assumes mutex is held on call */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    while ((error == SYS_OK) && FULL(stream)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        error = sysEventWait(connection->otherProcess, stream->hasSpace, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        if (error == SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            CHECK_ERROR(enterMutex(stream, connection->shutdown));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
signalSpace(Stream *stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    return sysEventSignal(stream->hasSpace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
 * Enter/exit with stream mutex held.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
 * On error, does not hold the stream mutex.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
waitForData(SharedMemoryConnection *connection, Stream *stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    jint error = SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    /* Assumes mutex is held on call */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    while ((error == SYS_OK) && EMPTY(stream)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        error = sysEventWait(connection->otherProcess, stream->hasData, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        if (error == SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            CHECK_ERROR(enterMutex(stream, connection->shutdown));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
signalData(Stream *stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    return sysEventSignal(stream->hasData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
closeStream(Stream *stream, jboolean linger)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * Lock stream during close - ignore shutdown event as we are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * closing down and shutdown should be signalled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    CHECK_ERROR(enterMutex(stream, NULL));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    /* mark the stream as closed */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    stream->state = STATE_CLOSED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    /* wake up waitForData() if it is in sysEventWait() */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    sysEventSignal(stream->hasData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    sysEventClose(stream->hasData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    /* wake up waitForSpace() if it is in sysEventWait() */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    sysEventSignal(stream->hasSpace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    sysEventClose(stream->hasSpace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     * If linger requested then give the stream a few seconds to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * drain before closing it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    if (linger) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        int attempts = 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        while (!EMPTY(stream) && attempts>0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            sysSleep(200);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            CHECK_ERROR(enterMutex(stream, NULL));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            attempts--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    sysIPMutexClose(stream->mutex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
 * Server creates stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
createStream(char *name, Stream *stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    char prefix[MAX_IPC_PREFIX];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    sprintf(prefix, "%s.mutex", name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    error = createWithGeneratedName(prefix, stream->shared->mutexName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                                    createMutex, &stream->mutex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    sprintf(prefix, "%s.hasData", name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    error = createWithGeneratedName(prefix, stream->shared->hasDataEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                                    createEvent, &stream->hasData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        (void)closeStream(stream, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    sprintf(prefix, "%s.hasSpace", name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    error = createWithGeneratedName(prefix, stream->shared->hasSpaceEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                                    createEvent, &stream->hasSpace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        (void)closeStream(stream, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    stream->shared->readOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    stream->shared->writeOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    stream->shared->isFull = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    stream->state = STATE_OPEN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
 * Initialization for the stream opened by the other process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
openStream(Stream *stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    CHECK_ERROR(sysIPMutexOpen(stream->shared->mutexName, &stream->mutex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    error = sysEventOpen(stream->shared->hasDataEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                             &stream->hasData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        (void)closeStream(stream, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    error = sysEventOpen(stream->shared->hasSpaceEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                             &stream->hasSpace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        (void)closeStream(stream, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    stream->state = STATE_OPEN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
/********************************************************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
static SharedMemoryConnection *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
allocConnection(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     * TO DO: Track all allocated connections for clean shutdown?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    SharedMemoryConnection *conn = (*callback->alloc)(sizeof(SharedMemoryConnection));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    if (conn != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        memset(conn, 0, sizeof(SharedMemoryConnection));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
    return conn;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
freeConnection(SharedMemoryConnection *connection)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    (*callback->free)(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
closeConnection(SharedMemoryConnection *connection)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     * Signal all threads accessing this connection that we are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * shutting down.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    if (connection->shutdown) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        sysEventSignal(connection->shutdown);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
    (void)closeStream(&connection->outgoing, JNI_TRUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    (void)closeStream(&connection->incoming, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    if (connection->sharedMemory) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        sysSharedMemClose(connection->sharedMemory, connection->shared);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    if (connection->otherProcess) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        sysProcessClose(connection->otherProcess);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     * Ideally we should close the connection->shutdown event and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
     * free the connection structure. However as closing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
     * connection is asynchronous it means that other threads may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
     * still be accessing the connection structure. On Win32 this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     * means we leak 132 bytes and one event per connection. This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     * memory will be reclaim at process exit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     * if (connection->shutdown)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     *     sysEventClose(connection->shutdown);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     * freeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
 * For client: connect to the shared memory.  Open incoming and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
 * outgoing streams.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
openConnection(SharedMemoryTransport *transport, jlong otherPID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
               SharedMemoryConnection **connectionPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
    SharedMemoryConnection *connection = allocConnection();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    if (connection == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        return SYS_NOMEM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
    sprintf(connection->name, "%s.%ld", transport->name, sysProcessGetID());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    error = sysSharedMemOpen(connection->name, &connection->sharedMemory,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                             &connection->shared);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
    /* This process is the client */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
    connection->incoming.shared = &connection->shared->toClient;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
    connection->outgoing.shared = &connection->shared->toServer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    error = openStream(&connection->incoming);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    error = openStream(&connection->outgoing);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    error = sysProcessOpen(otherPID, &connection->otherProcess);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * Create an event that signals that the connection is shutting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     * down. The event is unnamed as it's process local, and is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     * manually reset (so that signalling the event will signal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
     * all threads waiting on it).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    error = sysEventCreate(NULL, &connection->shutdown, JNI_TRUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    *connectionPtr = connection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
 * For server: create the shared memory.  Create incoming and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
 * outgoing streams.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
createConnection(SharedMemoryTransport *transport, jlong otherPID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                 SharedMemoryConnection **connectionPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    char streamPrefix[MAX_IPC_NAME];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    SharedMemoryConnection *connection = allocConnection();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    if (connection == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        return SYS_NOMEM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    sprintf(connection->name, "%s.%ld", transport->name, otherPID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    error = sysSharedMemCreate(connection->name, sizeof(SharedMemory),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                               &connection->sharedMemory, &connection->shared);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    memset(connection->shared, 0, sizeof(SharedMemory));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    /* This process is the server */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    connection->incoming.shared = &connection->shared->toServer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    connection->outgoing.shared = &connection->shared->toClient;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    strcpy(streamPrefix, connection->name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    strcat(streamPrefix, ".ctos");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    error = createStream(streamPrefix, &connection->incoming);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    strcpy(streamPrefix, connection->name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
    strcat(streamPrefix, ".stoc");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    error = createStream(streamPrefix, &connection->outgoing);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
    error = sysProcessOpen(otherPID, &connection->otherProcess);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * Create an event that signals that the connection is shutting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     * down. The event is unnamed as it's process local, and is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * manually reset (so that a signalling the event will signal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     * all threads waiting on it).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    error = sysEventCreate(NULL, &connection->shutdown, JNI_TRUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    *connectionPtr = connection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
/********************************************************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
static SharedMemoryTransport *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
allocTransport(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * TO DO: Track all allocated transports for clean shutdown?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    return (*callback->alloc)(sizeof(SharedMemoryTransport));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
freeTransport(SharedMemoryTransport *transport)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
    (*callback->free)(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
closeTransport(SharedMemoryTransport *transport)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    sysIPMutexClose(transport->mutex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    sysEventClose(transport->acceptEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    sysEventClose(transport->attachEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    sysSharedMemClose(transport->sharedMemory, transport->shared);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
    freeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
openTransport(const char *address, SharedMemoryTransport **transportPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    SharedMemoryTransport *transport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    transport = allocTransport();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    if (transport == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        return SYS_NOMEM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    memset(transport, 0, sizeof(*transport));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
    if (strlen(address) >= MAX_IPC_PREFIX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        char buf[128];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        sprintf(buf, "Error: address strings longer than %d characters are invalid\n", MAX_IPC_PREFIX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        setLastErrorMsg(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        return SYS_ERR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    error = sysSharedMemOpen(address, &transport->sharedMemory, &transport->shared);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
    strcpy(transport->name, address);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
    error = sysIPMutexOpen(transport->shared->mutexName, &transport->mutex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    error = sysEventOpen(transport->shared->acceptEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                             &transport->acceptEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    error = sysEventOpen(transport->shared->attachEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
                             &transport->attachEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    *transportPtr = transport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
createTransport(const char *address, SharedMemoryTransport **transportPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    SharedMemoryTransport *transport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    char prefix[MAX_IPC_PREFIX];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
    transport = allocTransport();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    if (transport == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        return SYS_NOMEM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    memset(transport, 0, sizeof(*transport));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    if ((address == NULL) || (address[0] == '\0')) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        SharedMemoryArg arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        arg.size = sizeof(SharedListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        error = createWithGeneratedName("javadebug", transport->name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                                        createSharedMem, &arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        transport->shared = arg.start;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        transport->sharedMemory = arg.memory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        if (strlen(address) >= MAX_IPC_PREFIX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            char buf[128];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            sprintf(buf, "Error: address strings longer than %d characters are invalid\n", MAX_IPC_PREFIX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            setLastErrorMsg(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            return SYS_ERR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        strcpy(transport->name, address);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        error = sysSharedMemCreate(address, sizeof(SharedListener),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                                   &transport->sharedMemory, &transport->shared);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    memset(transport->shared, 0, sizeof(SharedListener));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
    transport->shared->acceptingPID = sysProcessGetID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    sprintf(prefix, "%s.mutex", transport->name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    error = createWithGeneratedName(prefix, transport->shared->mutexName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                                    createMutex, &transport->mutex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
    sprintf(prefix, "%s.accept", transport->name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    error = createWithGeneratedName(prefix, transport->shared->acceptEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                                    createEvent, &transport->acceptEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
    sprintf(prefix, "%s.attach", transport->name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    error = createWithGeneratedName(prefix, transport->shared->attachEventName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                                    createEvent, &transport->attachEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
    *transportPtr = transport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
shmemBase_listen(const char *address, SharedMemoryTransport **transportPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    int error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    error = createTransport(address, transportPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
    if (error == SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
        (*transportPtr)->shared->isListening = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
shmemBase_accept(SharedMemoryTransport *transport,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                 long timeout,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
                 SharedMemoryConnection **connectionPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
    SharedMemoryConnection *connection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
    CHECK_ERROR(sysEventWait(NULL, transport->attachEvent, timeout));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
    error = createConnection(transport, transport->shared->attachingPID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                             &connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
         * Reject the attacher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        transport->shared->isAccepted = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        sysEventSignal(transport->acceptEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        freeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
    transport->shared->isAccepted = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
    error = sysEventSignal(transport->acceptEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
         * No real point trying to reject it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
    *connectionPtr = connection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
doAttach(SharedMemoryTransport *transport, long timeout)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
    transport->shared->attachingPID = sysProcessGetID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
    CHECK_ERROR(sysEventSignal(transport->attachEvent));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
    CHECK_ERROR(sysEventWait(NULL, transport->acceptEvent, timeout));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
shmemBase_attach(const char *addressString, long timeout, SharedMemoryConnection **connectionPtr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
    int error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
    SharedMemoryTransport *transport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
    jlong acceptingPID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    error = openTransport(addressString, &transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
    /* lock transport - no additional event to wait on as no connection yet */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
    error = sysIPMutexEnter(transport->mutex, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        setLastError(error);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    if (transport->shared->isListening) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        error = doAttach(transport, timeout);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        if (error == SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
            acceptingPID = transport->shared->acceptingPID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
        /* Not listening: error */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        error = SYS_ERR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    sysIPMutexExit(transport->mutex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    error = openConnection(transport, acceptingPID, connectionPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
    closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
    return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
shmemBase_closeConnection(SharedMemoryConnection *connection)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
    closeConnection(connection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
shmemBase_closeTransport(SharedMemoryTransport *transport)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    closeTransport(transport);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
shmemBase_sendByte(SharedMemoryConnection *connection, jbyte data)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
    Stream *stream = &connection->outgoing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    SharedStream *shared = stream->shared;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
    int offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    CHECK_ERROR(enterMutex(stream, connection->shutdown));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    CHECK_ERROR(waitForSpace(connection, stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    SHMEM_ASSERT(!FULL(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
    offset = shared->writeOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
    shared->buffer[offset] = data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
    shared->writeOffset = ADD_OFFSET(offset, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
    shared->isFull = (shared->readOffset == shared->writeOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
    STREAM_INVARIANT(stream);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
    CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
    CHECK_ERROR(signalData(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
shmemBase_receiveByte(SharedMemoryConnection *connection, jbyte *data)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
    Stream *stream = &connection->incoming;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    SharedStream *shared = stream->shared;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
    int offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
    CHECK_ERROR(enterMutex(stream, connection->shutdown));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
    CHECK_ERROR(waitForData(connection, stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
    SHMEM_ASSERT(!EMPTY(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    offset = shared->readOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
    *data = shared->buffer[offset];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
    shared->readOffset = ADD_OFFSET(offset, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
    shared->isFull = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
    STREAM_INVARIANT(stream);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
    CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
    CHECK_ERROR(signalSpace(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
sendBytes(SharedMemoryConnection *connection, const void *bytes, jint length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
    Stream *stream = &connection->outgoing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
    SharedStream *shared = stream->shared;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    jint fragmentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
    jint fragmentLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    jint index = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    jint maxLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    CHECK_ERROR(enterMutex(stream, connection->shutdown));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
    while (index < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
        CHECK_ERROR(waitForSpace(connection, stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
        SHMEM_ASSERT(!FULL(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
        fragmentStart = shared->writeOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
        if (fragmentStart < shared->readOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            maxLength = shared->readOffset - fragmentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
            maxLength = SHARED_BUFFER_SIZE - fragmentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
        fragmentLength = MIN(maxLength, length - index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
        memcpy(shared->buffer + fragmentStart, (jbyte *)bytes + index, fragmentLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
        shared->writeOffset = ADD_OFFSET(fragmentStart, fragmentLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
        index += fragmentLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
        shared->isFull = (shared->readOffset == shared->writeOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        STREAM_INVARIANT(stream);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
        CHECK_ERROR(signalData(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
    CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
 * Send packet header followed by data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
shmemBase_sendPacket(SharedMemoryConnection *connection, const jdwpPacket *packet)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
    jint data_length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
    CHECK_ERROR(sendBytes(connection, &packet->type.cmd.id, sizeof(jint)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
    CHECK_ERROR(sendBytes(connection, &packet->type.cmd.flags, sizeof(jbyte)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
    if (packet->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
        CHECK_ERROR(sendBytes(connection, &packet->type.reply.errorCode, sizeof(jshort)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
        CHECK_ERROR(sendBytes(connection, &packet->type.cmd.cmdSet, sizeof(jbyte)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        CHECK_ERROR(sendBytes(connection, &packet->type.cmd.cmd, sizeof(jbyte)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
    data_length = packet->type.cmd.len - 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
    SHMEM_GUARANTEE(data_length >= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
    CHECK_ERROR(sendBytes(connection, &data_length, sizeof(jint)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
    if (data_length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        CHECK_ERROR(sendBytes(connection, packet->type.cmd.data, data_length));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
static jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
receiveBytes(SharedMemoryConnection *connection, void *bytes, jint length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
    Stream *stream = &connection->incoming;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
    SharedStream *shared = stream->shared;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
    jint fragmentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
    jint fragmentLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
    jint index = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
    jint maxLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
    CHECK_ERROR(enterMutex(stream, connection->shutdown));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
    while (index < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
        CHECK_ERROR(waitForData(connection, stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
        SHMEM_ASSERT(!EMPTY(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
        fragmentStart = shared->readOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
        if (fragmentStart < shared->writeOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
            maxLength = shared->writeOffset - fragmentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
            maxLength = SHARED_BUFFER_SIZE - fragmentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
        fragmentLength = MIN(maxLength, length - index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
        memcpy((jbyte *)bytes + index, shared->buffer + fragmentStart, fragmentLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
        shared->readOffset = ADD_OFFSET(fragmentStart, fragmentLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
        index += fragmentLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
        shared->isFull = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
        STREAM_INVARIANT(stream);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
        CHECK_ERROR(signalSpace(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
    CHECK_ERROR(leaveMutex(stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
 * Read packet header and insert into packet structure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
 * Allocate space for the data and fill it in.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
shmemBase_receivePacket(SharedMemoryConnection *connection, jdwpPacket *packet)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
    jint data_length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
    clearLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
    CHECK_ERROR(receiveBytes(connection, &packet->type.cmd.id, sizeof(jint)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
    CHECK_ERROR(receiveBytes(connection, &packet->type.cmd.flags, sizeof(jbyte)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
    if (packet->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        CHECK_ERROR(receiveBytes(connection, &packet->type.reply.errorCode, sizeof(jshort)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        CHECK_ERROR(receiveBytes(connection, &packet->type.cmd.cmdSet, sizeof(jbyte)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
        CHECK_ERROR(receiveBytes(connection, &packet->type.cmd.cmd, sizeof(jbyte)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
    CHECK_ERROR(receiveBytes(connection, &data_length, sizeof(jint)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
    if (data_length < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
        return SYS_ERR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
    } else if (data_length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
        packet->type.cmd.len = 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
        packet->type.cmd.data = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
        packet->type.cmd.len = data_length + 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        packet->type.cmd.data = (*callback->alloc)(data_length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
        if (packet->type.cmd.data == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
            return SYS_ERR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
        error = receiveBytes(connection, packet->type.cmd.data, data_length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
        if (error != SYS_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
            (*callback->free)(packet->type.cmd.data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
            return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
shmemBase_name(struct SharedMemoryTransport *transport, char **name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
    *name = transport->name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
    return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
shmemBase_getlasterror(char *msg, jint size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
    char *errstr = (char *)sysTlsGet(tlsIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
    if (errstr != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
        strcpy(msg, errstr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
        return SYS_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
        return SYS_ERR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
exitTransportWithError(char *message, char *fileName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
                       char *date, int lineNumber)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
    JNIEnv *env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
    jint error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
    char buffer[500];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
    sprintf(buffer, "Shared Memory Transport \"%s\" (%s), line %d: %s\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
            fileName, date, lineNumber, message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
    error = (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
    if (error != JNI_OK) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
         * We're forced into a direct call to exit()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
        fprintf(stderr, "%s", buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        exit(-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
        (*env)->FatalError(env, buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
}