SlotTableStack.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.corba.se.impl.interceptors;
27
28import org.omg.CORBA.CompletionStatus;
29import org.omg.CORBA.INTERNAL;
30import org.omg.PortableInterceptor.Current;
31import org.omg.PortableInterceptor.InvalidSlot;
32
33import com.sun.corba.se.impl.corba.AnyImpl;
34
35import com.sun.corba.se.impl.logging.InterceptorsSystemException;
36import com.sun.corba.se.spi.logging.CORBALogDomains;
37
38import com.sun.corba.se.spi.orb.ORB;
39
40/**
41 * SlotTableStack is the container of SlotTable instances for each thread
42 */
43public class SlotTableStack
44{
45    // SlotTablePool is the container for reusable SlotTables'
46    private class SlotTablePool {
47
48        // Contains a list of reusable SlotTable
49        private SlotTable[] pool;
50
51        // High water mark for the pool
52        // If the pool size reaches this limit then putSlotTable will
53        // not put SlotTable to the pool.
54        private final int  HIGH_WATER_MARK = 5;
55
56        // currentIndex points to the last SlotTable in the list
57        private int currentIndex;
58
59        SlotTablePool( ) {
60            pool = new SlotTable[HIGH_WATER_MARK];
61            currentIndex = 0;
62        }
63
64        /**
65         * Puts SlotTable to the re-usable pool.
66         */
67        void putSlotTable( SlotTable table ) {
68            // If there are enough SlotTables in the pool, then don't add
69            // this table to the pool.
70            if( currentIndex >= HIGH_WATER_MARK ) {
71                // Let the garbage collector collect it.
72                return;
73            }
74            pool[currentIndex] = table;
75            currentIndex++;
76        }
77
78        /**
79         * Gets SlotTable from the re-usable pool.
80         */
81        SlotTable getSlotTable( ) {
82            // If there are no entries in the pool then return null
83            if( currentIndex == 0 ) {
84                return null;
85            }
86            // Works like a stack, Gets the last one added first
87            currentIndex--;
88            return pool[currentIndex];
89        }
90    }
91
92    // Contains all the active SlotTables for each thread.
93    // The List is made to behave like a stack.
94    private java.util.List tableContainer;
95
96    // Keeps track of number of PICurrents in the stack.
97    private int currentIndex;
98
99    // For Every Thread there will be a pool of re-usable SlotTables'
100    // stored in SlotTablePool
101    private SlotTablePool tablePool;
102
103    // The ORB associated with this slot table stack
104    private ORB orb;
105
106    private InterceptorsSystemException wrapper ;
107
108    /**
109     * Constructs the stack and and SlotTablePool
110     */
111    SlotTableStack( ORB orb, SlotTable table ) {
112       this.orb = orb;
113       wrapper = InterceptorsSystemException.get( orb, CORBALogDomains.RPC_PROTOCOL ) ;
114
115       currentIndex = 0;
116       tableContainer = new java.util.ArrayList( );
117       tablePool = new SlotTablePool( );
118       // SlotTableStack will be created with one SlotTable on the stack.
119       // This table is used as the reference to query for number of
120       // allocated slots to create other slottables.
121       tableContainer.add( currentIndex, table );
122       currentIndex++;
123    }
124
125
126    /**
127     * pushSlotTable  pushes a fresh Slot Table on to the stack by doing the
128     * following,
129     * 1: Checks to see if there is any SlotTable in SlotTablePool
130     *    If present then use that instance to push into the SlotTableStack
131     *
132     * 2: If there is no SlotTable in the pool, then creates a new one and
133     *    pushes that into the SlotTableStack
134     */
135    void pushSlotTable( ) {
136        SlotTable table = tablePool.getSlotTable( );
137        if( table == null ) {
138            // get an existing PICurrent to get the slotSize
139            SlotTable tableTemp = peekSlotTable();
140            table = new SlotTable( orb, tableTemp.getSize( ));
141        }
142        // NOTE: Very important not to always "add" - otherwise a memory leak.
143        if (currentIndex == tableContainer.size()) {
144            // Add will cause the table to grow.
145            tableContainer.add( currentIndex, table );
146        } else if (currentIndex > tableContainer.size()) {
147            throw wrapper.slotTableInvariant( new Integer( currentIndex ),
148                new Integer( tableContainer.size() ) ) ;
149        } else {
150            // Set will override unused slots.
151            tableContainer.set( currentIndex, table );
152        }
153        currentIndex++;
154    }
155
156    /**
157     * popSlotTable does the following
158     * 1: pops the top SlotTable in the SlotTableStack
159     *
160     * 2: resets the slots in the SlotTable which resets the slotvalues to
161     *    null if there are any previous sets.
162     *
163     * 3: puts the reset SlotTable into the SlotTablePool to reuse
164     */
165    void  popSlotTable( ) {
166        if( currentIndex <= 1 ) {
167            // Do not pop the SlotTable, If there is only one.
168            // This should not happen, But an extra check for safety.
169            throw wrapper.cantPopOnlyPicurrent() ;
170        }
171        currentIndex--;
172        SlotTable table = (SlotTable)tableContainer.get( currentIndex );
173        tableContainer.set( currentIndex, null ); // Do not leak memory.
174        table.resetSlots( );
175        tablePool.putSlotTable( table );
176    }
177
178    /**
179     * peekSlotTable gets the top SlotTable from the SlotTableStack without
180     * popping.
181     */
182    SlotTable peekSlotTable( ) {
183       return (SlotTable) tableContainer.get( currentIndex - 1);
184    }
185
186}
187
188// End of file.
189