Skip to content

Commit 71a5791

Browse files
committed
fix possible key collision problem with pools, potential race with incr/decr, and some logging
1 parent 0475f28 commit 71a5791

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

src/com/danga/MemCached/MemCachedClient.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,86 @@ public long getCounter( String key, Integer hashCode ) {
805805
return counter;
806806
}
807807

808+
/**
809+
* Thread safe way to initialize and increment a counter.
810+
*
811+
* @param key key where the data is stored
812+
* @return value of incrementer
813+
*/
814+
public long addOrIncr( String key ) {
815+
return addOrIncr( key, 0, null );
816+
}
817+
818+
/**
819+
* Thread safe way to initialize and increment a counter.
820+
*
821+
* @param key key where the data is stored
822+
* @param inc value to set or increment by
823+
* @return value of incrementer
824+
*/
825+
public long addOrIncr( String key, long inc ) {
826+
return addOrIncr( key, inc, null );
827+
}
828+
829+
/**
830+
* Thread safe way to initialize and increment a counter.
831+
*
832+
* @param key key where the data is stored
833+
* @param inc value to set or increment by
834+
* @param hashCode if not null, then the int hashcode to use
835+
* @return value of incrementer
836+
*/
837+
public long addOrIncr( String key, long inc, Integer hashCode ) {
838+
boolean ret = set( "add", key, new Long( inc ), null, hashCode, true );
839+
840+
if ( ret ) {
841+
return inc;
842+
}
843+
else {
844+
return incrdecr( "incr", key, inc, hashCode );
845+
}
846+
}
847+
848+
/**
849+
* Thread safe way to initialize and decrement a counter.
850+
*
851+
* @param key key where the data is stored
852+
* @return value of incrementer
853+
*/
854+
public long addOrDecr( String key ) {
855+
return addOrDecr( key, 0, null );
856+
}
857+
858+
/**
859+
* Thread safe way to initialize and decrement a counter.
860+
*
861+
* @param key key where the data is stored
862+
* @param inc value to set or increment by
863+
* @return value of incrementer
864+
*/
865+
public long addOrDecr( String key, long inc ) {
866+
return addOrDecr( key, inc, null );
867+
}
868+
869+
/**
870+
* Thread safe way to initialize and decrement a counter.
871+
*
872+
* @param key key where the data is stored
873+
* @param inc value to set or increment by
874+
* @param hashCode if not null, then the int hashcode to use
875+
* @return value of incrementer
876+
*/
877+
public long addOrDecr( String key, long inc, Integer hashCode ) {
878+
boolean ret = set( "add", key, new Long( inc ), null, hashCode, true );
879+
880+
if ( ret ) {
881+
return inc;
882+
}
883+
else {
884+
return incrdecr( "decr", key, inc, hashCode );
885+
}
886+
}
887+
808888
/**
809889
* Increment the value at the specified key by 1, and then return it.
810890
*

src/com/danga/MemCached/SockIOPool.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,13 @@ public SockIO getConnection( String host ) {
895895
}
896896
else {
897897
// not connected, so we need to remove it
898-
log.error( "++++ socket in avail pool is not connected: " + socket.toString() + " for host: " + host );
898+
try {
899+
socket.trueClose();
900+
}
901+
catch ( Exception ex ) {
902+
log.debug( "++++ error trying to true close the socket" );
903+
}
904+
899905
socket = null;
900906

901907
// remove from avail pool
@@ -966,7 +972,7 @@ protected void addSocketToPool( Map<String,Map<SockIO,Long>> pool, String host,
966972
}
967973

968974
Map<SockIO,Long> sockets =
969-
new HashMap<SockIO,Long>();
975+
new IdentityHashMap<SockIO,Long>();
970976

971977
sockets.put( socket, new Long( System.currentTimeMillis() ) );
972978
pool.put( host, sockets );

0 commit comments

Comments
 (0)