@@ -795,74 +795,86 @@ class KeyManager {
795
795
// Make sure to not run in parallel
796
796
if (_uploadingFuture != null ) {
797
797
if (skipIfInProgress) return ;
798
- await _uploadingFuture;
798
+ try {
799
+ await _uploadingFuture;
800
+ } finally {
801
+ // shouldn't be necessary, since it will be unset already by the other process that started it, but just to be safe, also unset the future here
802
+ _uploadingFuture = null ;
803
+ }
799
804
}
800
- final completer = Completer <void >();
801
- _uploadingFuture = completer.future;
802
805
803
- await client.userDeviceKeysLoading;
804
- try {
805
- if (! (await isCached ())) {
806
- return ; // we can't backup anyways
807
- }
808
- final dbSessions = await database.getInboundGroupSessionsToUpload ();
809
- if (dbSessions.isEmpty) {
810
- return ; // nothing to do
811
- }
812
- final privateKey =
813
- base64decodeUnpadded ((await encryption.ssss.getCached (megolmKey))! );
814
- // decryption is needed to calculate the public key and thus see if the claimed information is in fact valid
815
- final decryption = olm.PkDecryption ();
816
- final info = await getRoomKeysBackupInfo (false );
817
- String backupPubKey;
806
+ Future <void > uploadInternal () async {
818
807
try {
819
- backupPubKey = decryption. init_with_private_key (privateKey) ;
808
+ await client.userDeviceKeysLoading ;
820
809
821
- if (info.algorithm !=
822
- BackupAlgorithm .mMegolmBackupV1Curve25519AesSha2 ||
823
- info.authData['public_key' ] != backupPubKey) {
824
- return ;
810
+ if (! (await isCached ())) {
811
+ return ; // we can't backup anyways
825
812
}
826
- final args = GenerateUploadKeysArgs (
827
- pubkey: backupPubKey,
828
- dbSessions: < DbInboundGroupSessionBundle > [],
829
- userId: userID,
830
- );
831
- // we need to calculate verified beforehand, as else we pass a closure to an isolate
832
- // with 500 keys they do, however, noticably block the UI, which is why we give brief async suspentions in here
833
- // so that the event loop can progress
834
- var i = 0 ;
835
- for (final dbSession in dbSessions) {
836
- final device =
837
- client.getUserDeviceKeysByCurve25519Key (dbSession.senderKey);
838
- args.dbSessions.add (DbInboundGroupSessionBundle (
839
- dbSession: dbSession,
840
- verified: device? .verified ?? false ,
841
- ));
842
- i++ ;
843
- if (i > 10 ) {
844
- await Future .delayed (Duration (milliseconds: 1 ));
845
- i = 0 ;
846
- }
813
+ final dbSessions = await database.getInboundGroupSessionsToUpload ();
814
+ if (dbSessions.isEmpty) {
815
+ return ; // nothing to do
847
816
}
848
- final roomKeys =
849
- await client.nativeImplementations.generateUploadKeys (args);
850
- Logs ().i ('[Key Manager] Uploading ${dbSessions .length } room keys...' );
851
- // upload the payload...
852
- await client.putRoomKeys (info.version, roomKeys);
853
- // and now finally mark all the keys as uploaded
854
- // no need to optimze this, as we only run it so seldomly and almost never with many keys at once
855
- for (final dbSession in dbSessions) {
856
- await database.markInboundGroupSessionAsUploaded (
857
- dbSession.roomId, dbSession.sessionId);
817
+ final privateKey =
818
+ base64decodeUnpadded ((await encryption.ssss.getCached (megolmKey))! );
819
+ // decryption is needed to calculate the public key and thus see if the claimed information is in fact valid
820
+ final decryption = olm.PkDecryption ();
821
+ final info = await getRoomKeysBackupInfo (false );
822
+ String backupPubKey;
823
+ try {
824
+ backupPubKey = decryption.init_with_private_key (privateKey);
825
+
826
+ if (info.algorithm !=
827
+ BackupAlgorithm .mMegolmBackupV1Curve25519AesSha2 ||
828
+ info.authData['public_key' ] != backupPubKey) {
829
+ decryption.free ();
830
+ return ;
831
+ }
832
+ final args = GenerateUploadKeysArgs (
833
+ pubkey: backupPubKey,
834
+ dbSessions: < DbInboundGroupSessionBundle > [],
835
+ userId: userID,
836
+ );
837
+ // we need to calculate verified beforehand, as else we pass a closure to an isolate
838
+ // with 500 keys they do, however, noticably block the UI, which is why we give brief async suspentions in here
839
+ // so that the event loop can progress
840
+ var i = 0 ;
841
+ for (final dbSession in dbSessions) {
842
+ final device =
843
+ client.getUserDeviceKeysByCurve25519Key (dbSession.senderKey);
844
+ args.dbSessions.add (DbInboundGroupSessionBundle (
845
+ dbSession: dbSession,
846
+ verified: device? .verified ?? false ,
847
+ ));
848
+ i++ ;
849
+ if (i > 10 ) {
850
+ await Future .delayed (Duration (milliseconds: 1 ));
851
+ i = 0 ;
852
+ }
853
+ }
854
+ final roomKeys =
855
+ await client.nativeImplementations.generateUploadKeys (args);
856
+ Logs ().i ('[Key Manager] Uploading ${dbSessions .length } room keys...' );
857
+ // upload the payload...
858
+ await client.putRoomKeys (info.version, roomKeys);
859
+ // and now finally mark all the keys as uploaded
860
+ // no need to optimze this, as we only run it so seldomly and almost never with many keys at once
861
+ for (final dbSession in dbSessions) {
862
+ await database.markInboundGroupSessionAsUploaded (
863
+ dbSession.roomId, dbSession.sessionId);
864
+ }
865
+ } finally {
866
+ decryption.free ();
858
867
}
859
- } finally {
860
- decryption. free ( );
868
+ } catch (e, s) {
869
+ Logs (). e ( '[Key Manager] Error uploading room keys' , e, s );
861
870
}
862
- } catch (e, s) {
863
- Logs ().e ('[Key Manager] Error uploading room keys' , e, s);
871
+ }
872
+
873
+ _uploadingFuture = uploadInternal ();
874
+ try {
875
+ await _uploadingFuture;
864
876
} finally {
865
- completer. complete () ;
877
+ _uploadingFuture = null ;
866
878
}
867
879
}
868
880
@@ -1187,12 +1199,12 @@ RoomKeys generateUploadKeysImplementation(GenerateUploadKeysArgs args) {
1187
1199
},
1188
1200
);
1189
1201
}
1202
+ enc.free ();
1190
1203
return roomKeys;
1191
1204
} catch (e, s) {
1192
1205
Logs ().e ('[Key Manager] Error generating payload' , e, s);
1193
- rethrow ;
1194
- } finally {
1195
1206
enc.free ();
1207
+ rethrow ;
1196
1208
}
1197
1209
}
1198
1210
0 commit comments